How to manage state on a React component that can have state changed from a parent or from events on it?

I am trying to create a custom checkbox component (three states, actually, but it doesn’t matter, except to say that I’m not just using INPUT), and I’m not sure how to do this to change the “verification check” from clicking on myself and from a set of values ​​coming from a parent.

I am currently working as a self-contained component that accepts onChange support with a handler callback that it calls to send the value of the parent component after clicks. It uses state to save the check referenced by the display.

If it were just an exponential control, with a value controlled externally, I would use props, of course. If it were only a self-contained checkbox element that accepted the initial value, but only responded to clicks, I would use a state like me, but my problem is that I want it to be available to turn on and off, and allow parent enable and disable it.

I am starting to react and “React”, so I suspect that I am just approaching this wrong. I get the impression that the right way to do this would only consist of a display-only component that passed clicks to the parent to deal with, and in turn received props updates to change values ​​from the parent, but that would do the component is much less reusable in my opinion.

So, how do I change the flag from both internal and parent sources?

Relevant links are also welcome.

+5
source share
3 answers

You can consider the flag as a mute component, which means that it does not contain any internal states, but only receives data from the outside through the details, and then visualizes them. You can see a detailed definition of dumb components here .

Meanwhile, when you click on the flag, such an event will be processed by the component's parent or the ancestor of the event, this is called the reverse data flow, which is described in Facebook Thinking in the blog response .

In addition, in order to decide which component should contain certain conditions, I consider the following recommendations to be very useful:

Remember: Response is a one-way flow of data across a component hierarchy. It may not be immediately clear which component should own which state. This is often the hardest part for beginners to understand , so follow these steps:

For each piece of state in your application:

  • Identify each component that displays something based on this state.
  • Find the common component of the owner (one component, first of all components that require state in the hierarchy).
  • Either the common owner or another component above in the hierarchy must own the state.
  • If you cannot find a component in which it makes sense to own the state, create a new component just to store the state and add it somewhere in the hierarchy above the usual owner component.

Pseudo-code snippet:

const Checkbox = React.createClass({ // Propagate the event to parents onClick(evt) { if (this.props.handleClick) { this.props.handleClick({checked: evt.target.value}); } }, render() { return ( this.props.checked ? <Input onClick={this.onClick} type="checkbox" label="Checkbox" checked></Input> : <Input onClick={this.onClick} type="checkbox" label="Checkbox"></Input> ); } }); const Container = React.createClass({ handleClick(evt) { // Change the container state, which eventually changes the checkbox view via props. this.setState({checked: evt.checked}); }, render() { return ( <div><Checkbox checked={this.state.checked} handleClick={this.handleClick}></Checkbox></div> ); } }); 
+7
source

You change it only from the parent.

 class ParentComponent extends React.Component{ handleChildCheck(){ this.setState({ childChecked: !this.state.childChecked }) } render(){ return( <ChildComponent checked={this.state.childChecked} handleCheck={this.handleChildCheck.bind(this)} /> ) } } 

Now, if you want to manage the checked state from <ChildComponent/> , just call this.props.handleCheck() from <ChildComponent/>

That way, the controls will always be available within <ChildComponent/> through this.props.handleCheck() within <ParentComponent/> through this.handleChildCheck() .

+3
source

Use querySelectorAll to search for your components. Add an event listener to track changes. When changing, run another SelectorAll query to find children and disable or enable. This may not satisfy all your needs, but it will help you get started in the right direction. This is simple javascript, so no other libraries are required.

 // Finds radios with class on-off and disables 'name-on' elements when // 'name' is off. function initOfOff() { var mains = document.querySelectorAll('.on-off'); for (var i = 0; i < mains.length; i++) { var el = mains[i]; var name = el.getAttribute('name'); el.addEventListener('click', function() { var value = this.getAttribute('value'); var children = document.querySelectorAll('.' + name + '-on'); for (var i = 0; i < children.length; i++) { var child = children[i]; child.checked = false; if (value == "off") { child.setAttribute('disabled', 'disabled'); } else { child.removeAttribute('disabled'); } } }); } } initOfOff() 
 <form name='myform'>power <input type='radio' value='on' class='on-off' name='power'>ON | <input type='radio' value='off' class='on-off' name='power'>Off <dir>lights <input type='radio' value='on' class='power-on' name='lights'>ON | <input type='radio' value='off' class='power-on' name='lights'>OFF </dir> </form> 
-2
source

Source: https://habr.com/ru/post/1238662/


All Articles