How to update parent's state?

≡放荡痞女 提交于 2020-01-23 17:58:26

问题


I am new to react and trying to update parent's state but no luck so far.

Component

class InputBox extends Component {
  constructor(props) {
    super(props);
    this.type = props.type;
  }
  render() {
    return (
      <div>
        <input type={this.type}/>
      </div>
    );
  }
}

Other container where I want to use this component to toggle password

constructor(props) {
  super(props);
  this.state = {
    type: 'password',
    wording: 'Show',
  };
  this.changeState = this.changeState.bind(this);
}

changeState() {
  const oldState = this.state.type;
  const isTextOrHide = (oldState === 'password');
  const newState = (isTextOrHide) ? 'text' : 'password';
  const newWord = (isTextOrHide) ? 'Hide' : 'Show';
  this.setState({
    type: newState,
    label: newWord,
  });
}

<Wrapper>
  <InputBox type={this.state.type} />
  <Toggle onClick={this.changeState}>{this.state.wording}</Toggle>
</Wrapper>

回答1:


You can do like this:

First, Parent component:

import React, { Component } from 'react';
import { InputBox} from './InputBox'

class componentName extends Component {
  state = {
    password: '',
    type: 'password',
    wording: 'Show',
  }

  handleShow = (word) => {
    this.setState({ wording: word })
  }

  handleChange = (e) => {
    if(!this.state.password){ 
      handleShow('Show')
    } else  {
      handleShow('Hide')
    }
    this.setState({ password: e.target.value })
  }

  render() {
    return (
      <div>
        <Wrapper>
          <InputBox
           name='password'  
           handleChange={this.handleChange} 
           password={this.state.password}
           type={this.state.type} /> . 
          <Toggle onClick={this.changeState}>{this.state.wording}
         </Toggle>
        </Wrapper>
      </div>
    );
  }
}

Now the child component:

import React from 'react';

export const InputBox = (props) => (
  <input onChange={props.handleChange} value={props.password} type={props.type}/>
)
  1. The state needs to always remain in the parent and then pass it down through props
  2. The children components usually are stateless, which means, they don't need to be a class (can be just a function that returns jsx ) and the most import, can't have state (state is only available in Class components)

Always pass the state down to children components Because no matter how far down the state is, by being passed through props it'll will always change the source, which in this case is the parent, the creator of the state

another important thing:

If you use arrow functions ES6 , there's no need to have a constructor to bind your functions.

Like this: handleSomething = () => { return ... }

another thing:

you don't need the constructor to set the state, you can simply do

state = { } 

and it automatically become part of the context this

Thinking this way you'll never fail.

Hope it helped you :)




回答2:


class Child extends Component{
    constructor(props){
       super(props);
    }

    render(){
       let { parentStateChange } = this.props;
       return <input type='text' onChange={parentStateChange}/>
    }
}

class Parent extends Component{
    constructor(props){
       super(props);
       this.state = {
           content: "Something"
       }
       this.parentStateChange = this.parentStateChange.bind(this);
    }

    parentStateChange(event){
       let value = event.target.value;
       this.setState({
           content: value
       })
    }

    render(){
       let { content } = this.state;
       return <div>
           <h2>{content}</h2>
           <Child parentStateChange={this.parentStateChange}></Child>
         </div>
    }
}

I did it by passing a Parent's method to child as a props. Then Child has use this method to change Parent's state. It's called as Callback Functions.

For More References

I think this is useful for you.




回答3:


A more generic (but possibly bad approach). Parent class has a function that is passed as callback to children and allows child calling setState directly. I can only see this useful in a tightly bound small component with a few children or just for proof of concept code.

/**
  * This allows children to set state of this object.
  * Might be a very bad approach, btw.
  * 
  * @param {object} newState - object to update state.
  * @param {func} cb - call back after state is updated.
  */
 doSetState = (newState, cb=null) => {
    const merge = { ...this.state, ...newState };
    cb ? this.setState(merge, cb) : this.setState(merge);
}


来源:https://stackoverflow.com/questions/44661549/how-to-update-parents-state

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!