
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
react-auto-controlled
Advanced tools
Component autonomous state control utilities in React class methods and React Hooks
A collection of React component libraries (both class methods and Hooks) for self-governing state values.
<AutoControlledComponent> (semantic-ui-react) is not exported.<AutoControlledComponent> (@stardust-ui/react) requires dependencies to other modules that you don't need.class components.Enter this library. Its utilities behave roughly in the manner you'd expect if you were to use <AutoControlledComponent>, with some differences. Include support for a Hook-based counterpart and you get react-auto-controlled.
You'll need React preinstalled in order to use this library.
NPM
npm install --save react
npm install --save react-auto-controlled
Yarn
yarn add react
yarn add react-auto-controlled
This package contains definitions for TypeScript.
You don't need to install a @types/react-auto-controlled module.
All examples are written in TypeScript. Pure JavaScript developers are encouraged to read along.
The examples below assume a component called <Counter> will be used this way:
import { Counter } from './Counter';
export function App() {
// Details:
// 1. Without a `prop`, the counter component starts at `0`, incrementing itself when its button is clicked.
// 2. With a `defaultProp`, the counter component starts at `20`, incrementing itself when its button is clicked.
// 3. With a `value`, the counter component will not update its value unless the user provides a `value` prop.
return (
<div>
<Counter />
<Counter defaultValue={20} defaultName="Cody" />
<Counter value={10} name="Charlie" />
</div>
);
}
For React v16.8+
Demo: https://github.com/andrewsantarin/react-16-auto-controlled-hook/tree/master/
Unlike a State Manager Class, a Hook only manages one slice of the state, similar to the React useState hook.
By using Hooks, you gain more control over which state you'd prefer to update. However, in the spirit of useState,
you have to invoke the state modifer one by one if you want to update multiple states at once.
import React, { useCallback } from 'react';
import { useAutoControlled } from 'react-auto-controlled';
interface CounterProps {
otherProp?: string;
value?: number;
defaultValue?: number;
name?: string;
defaultName?: string;
}
export function Counter(props) {
const [
value, // original React.useState pattern
setValue, // original React.useState pattern
trySetValue,
getDerivedValueFromProp
] = useAutoControlled(0, {
prop: props.value, // optional
defaultProp: props.defaultValue, // optional
});
const [
name, // original React.useState pattern
setName, // original React.useState pattern
trySetName,
getDerivedNameFromProp
] = useAutoControlled('Andrew', {
prop: props.name, // optional
defaultProp: props.defaultName, // optional
});
getDerivedValueFromProp(); // Similar to getDerivedStateFromProps, except no argument and state slice only.
getDerivedNameFromProp(); // Similar to getDerivedStateFromProps, except no argument and state slice only.
const handleClick = useCallback(() => {
trySetValue(value + 1);
trySetName('Bob');
}, [ trySetValue, value ]);
return (
<div>
<button onClick={handleClick}>
Value: <strong>{value}</strong>
</button>
<div>
Hello, {name}!
</div>
</div>
);
}
For React v16.3+
Demo: https://github.com/andrewsantarin/react-16-auto-controlled-class/tree/master/
The Class State Manager offers a set of methods in order to autocontrol state. Unlike <AutoControlledComponent>,
it's not an extension of the React Component class. You'll need to declare your own class component separately.
This approach was taken in order to reduce static attribute pollution on the component class, which can also
be potentially overridden by an unattentive developer. The manager's methods are immutable (Object.freeze(this)).
If you use earlier versions of React which aren't shipped with the
static getDerivedStateFromProps(nextProps, prevState)component function, refer to the legacy example instead.
import React, { Component } from 'react';
import { AutoControlledManager, AutoControlled } from 'react-auto-controlled';
interface CounterProps = {
otherProp?: string;
value?: number;
defaultValue?: number;
name?: string;
defaultName?: string;
};
type CounterState = Required<
Pick<CounterProps, 'value' | 'name'>
>;
const counterAutoControlledManager = new AutoControlledManager<AppState, AppProps>(
[
// A list of class component props you want to auto-control
'value',
'name',
],
{
// State initializer
getInitialAutoControlledState() {
return {
active: false,
name: 'Andrew',
level: 0,
};
}
}
);
export class Counter
extends Component<CounterProps, CounterState>
implements AutoControlled<CounterState> // Enforce the `.trySetState(maybeState, callback?)` class method.
{
// Use `constructor` if you have custom logic in the state / attribute / method assignment.
constructor(props: CounterProps) {
super(props);
this.state = counterAutoControlledManager.getInitialAutoControlledStateFromProps(props);
}
// Take this approach if you have zero custom logic. Just use `this.props`. Convenient!
state = counterAutoControlledManager.getInitialAutoControlledStateFromProps(this.props);
// Apply the manager functions to the corresponding component methods.
static getDerivedStateFromProps = counterAutoControlledManager.getDerivedStateFromProps;
trySetState = counterAutoControlledManager.trySetState;
handleClick = () => {
// Replace `this.setState()` with `this.trySetState()` to achieve auto-control.
this.trySetState({
value: this.state.value + 1,
name: 'Bob',
});
}
render() {
const { value, name } = this.state;
return (
<div>
<button onClick={this.handleClick}>
Value: <strong>{value}</strong>
</button>
<div>
Hello, {name}!
</div>
</div>
);
}
}
For React 15.0 ~ React 16.2
⚠️ This library has been tested with React v16.8.x. ⚠️
The maintainer(s) can't guarantee that this approach will always work.
Consider upgrading your project's React dependency to at least v16.3.
Demo: https://codesandbox.io/s/github/andrewsantarin/react-15-auto-controlled-class/tree/master/
The Class State Manager offers a set of methods in order to autocontrol state.
The static getDerivedStateFromProps(nextProps, prevState) component function, which this library intends to enhance, is unavailable to you in earlier version of React. You can subsitute it with a combination of:
componentWillReceiveProps(nextProps) lifecycle functionthis.state in the lifecycle implementation.import React, { Component } from 'react';
import { AutoControlledManager, AutoControlled } from 'react-auto-controlled';
interface CounterProps = {
otherProp?: string;
value?: number;
defaultValue?: number;
name?: string;
defaultName?: string;
};
type CounterState = Required<
Pick<CounterProps, 'value' | 'name'>
>;
const counterAutoControlledManager = new AutoControlledManager<AppState, AppProps>(
[
// A list of class component props you want to auto-control
'value',
'name',
],
{
// State initializer
getInitialAutoControlledState() {
return {
active: false,
name: 'Andrew',
level: 0,
};
}
}
);
export class Counter
extends Component<CounterProps, CounterState>
implements AutoControlled<CounterState> // Enforce the `.trySetState(maybeState, callback?)` class method.
{
// Use `constructor` if you have custom logic in the state / attribute / method assignment.
constructor(props: CounterProps) {
super(props);
this.state = counterAutoControlledManager.getInitialAutoControlledStateFromProps(props);
}
// Take this approach if you have zero custom logic. Just use `this.props`. Convenient!
state = counterAutoControlledManager.getInitialAutoControlledStateFromProps(this.props);
componentWillReceiveProps(nextProps: CounterProps) {
const newState = counterAutoControlledManager.getDerivedStateFromProps(
nextProps,
this.state // This should behave roughly like the `prevState` callback parameter.
);
if (newState === null) {
return;
}
// Apply the state changes.
this.setState(newState);
}
// Apply the manager functions to the corresponding component methods.
trySetState = counterAutoControlledManager.trySetState;
handleClick = () => {
// Replace `this.setState()` with `this.trySetState()` to achieve auto-control.
this.trySetState({
value: this.state.value + 1,
name: 'Bob',
});
}
render() {
const { value, name } = this.state;
return (
<div>
<button onClick={this.handleClick}>
Value: <strong>{value}</strong>
</button>
<div>
Hello, {name}!
</div>
</div>
);
}
}
This library is still very much a work in progress was hastily started so that it can be used immediately in bigger projects.
Ideas & support are more than welcome!
yarn develop.yarn test. If the tests fail, check the code again. Make sure the tests pass!yarn lint. Clean up all linting errors.See: LICENSE.md
MIT.
FAQs
Component autonomous state control utilities in React class methods and React Hooks
The npm package react-auto-controlled receives a total of 14,676 weekly downloads. As such, react-auto-controlled popularity was classified as popular.
We found that react-auto-controlled demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.