简体   繁体   中英

How to transfer states among components?

I'm new to React JS, I want to create a ToDo list app. I have App.js which is the main page and so I have created MainBlock component for App.js page which holds left and right side of my layout and in right side property it loads Form component which has input and button and saves input values to an array in state and in left side it loads List component which has a property named allTasks which prints all tasks. My problem is how can I transfer allTasks state from Form Component to App.js to pass it to List component property? In App.js :

<MainBlock
left={  
    <List allTasks={['خرید از فروشگاه', 'تعویض دستگیره درب منزل']} />} 
right={
    <Form />
} />

You can accomplish this by storing the tasks as state in the App component, and have Form pass up the state through a callback prop. This concept is called "lifting state up". Here's a guide about it: https://reactjs.org/docs/lifting-state-up.html

<MainBlock
  left={
    <List allTasks={this.state.allTasks} />
  }
  right={ 
    <Form onSubmit={allTasks => this.setState({ allTasks })} />
  }
/>
  1. Let tasks be a state of the MainBlock component. Pass this state down to the List component.

  2. Let the Form component expose a callback property (maybe onTaskCreated ) which is invoked when user complete creating a new task.

  3. Let MainBlock intercept onTaskCreated callbacks and update it's internal state with the new task, which causes it to re-render and thus passing down the new task list to the List component.

You are trying to achieve two way binding here. Unfortunately, React is a library that doesn't support two way binding by default. You can only pass in the values from Parent to Child to Sub-Child. However, the reverse is not true. In this case, you are trying to load props from Form to App that is from Child to Parent which is not possible.

You should make use of state containers such as Redux that overcomes this limitation by making the state of one component available to the other component.

You can store all your tasks in the state of the MainBlock component and pass functions to update the state by your form. Also, pass the state (tasks) of MainBlock to your List component. Updating your tasks to MainBlock will automatically pass the tasks to List. Later you could use a state management library like MobX and Redux.

It can be confusing passing data between components. Libraries like redux were created to make this "easier", but it can be done with simple React. To pass state information to children, you pass it into their props. To send data the other direction, you pass (from parent to child) a handler function that is called from the child and can affect the state of the parent (or be passed to it's parent) as needed.

I wrote a sample pen to help people wrap their heads around this. Hopefully it helps.

Something like:

<Child1 handleAdd={this.handleAdd.bind(this)} 
    handleSubtract={this.handleSubtract.bind(this)} 
/>

calls in the parent and and is accessed in the child as:

<Button onClick={this.onAdd.bind(this)}>
    add
</Button>&nbsp;
<Button onClick={this.props.handleSubtract.bind(this)}>
    subtract
</Button>

Then there is a function in the parent called handleAdd that can affect the parent state.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM