14

Let's say that my parent component got two child component :

Parent
| Child1
| Child2

I'am getting an input from Child2 and I'am passing it to the Parent component (until now, I know how to do). But then I need to pass that input to Child1 to update it's state.

How can I do that?

Mit
  • 339
  • 1
  • 7
  • 23

4 Answers4

21

Hope you can get the main idea - create a function in the Parent component that will change the value passed to the Child1. ReactJS: Why is passing the component initial state a prop an anti-pattern?

class Parent extends Component {
  constructor(props){
    super(props);
    this.state = {
      value: ""
    }
  }
  changeValue(value){
    this.setState({value});
  }
  render(){
    return (
      <div>
          <Child1 value={this.state.value}/>
          <Child2 changeValue={changeValue}/>
      </div>
    )
  }
}


class Child2 extends Component {
  constructor(props) {
    super(props);
    this.state={
      input: ""
    }
  }
  handleChange(e){
    var {value} = e.target;
    this.setState({
      input: value
    },() => this.props.changeValue(value));
  }
  render(){
    return (
      <div>
          <input value={this.state.input} onChange={this.handleChange}/>
      </div>
    )
  }
}



class Child1 extends Component {

  constructor(props) {
    super(props);
    this.state={value:''}
  }
  componentWillReceiveProps(nextProps) {
    this.setState({value: nextProps.value})
  }


  render(){
    return (
      <div>
          {this.props.value}
      </div>
    )
  }
}
Community
  • 1
  • 1
kurumkan
  • 2,635
  • 3
  • 31
  • 55
  • 3
    Thank you but I don't think that will work, you are passing props to your Child1 but what I want is to update it's state (your Child1 don't have any state value). – Mit May 01 '17 at 12:49
  • ok it has a state. But - it considered as antipattern - to update your state from props. – kurumkan May 01 '17 at 13:05
  • Thank you, but is it possible to do it whithaout declaring a state in the parent component? Like passing it "directly" from Child2 to Child1 through the parent component (I hope you understand what I mean). Because actually I want to pass the input of Child2 to the child of the child of Child1... I think one takes memory unnecessarily by declaring a state into each of this childs just to pass the information through the childs. – Mit May 01 '17 at 15:14
  • I guess - no! Otherwise use something like Redux. – kurumkan May 01 '17 at 15:15
  • Yes I was also thinking about Redux. Thanks for your help. – Mit May 01 '17 at 15:20
  • if your problem solved - pls tag related answer as a solution – kurumkan May 01 '17 at 16:56
  • I received a warning in console telling me to use `componentDidUpdate(prevProps)`. Both works. – BakaWaii Mar 05 '20 at 06:07
1

You can have a function in your child component that updates the state based on the value sent from the parent component. And you can access a function of the child component form the parent component using refs

Example

Parent:

class Parent extends React.Component {
     funcUpdateChild1 = () => {
          this.child1.updateState('value here');
     }
     render() {
          return (
              <Child1 ref={(ip) => {this.child1 = ip}} />
              <Child2 ref={(ip) => {this.child2 = ip}} />
         ) 
     }
}

Child1

class Child1 extends React.Component {
     updateState = (value) => {
         //use the value to set state here
     }
     render() {
          return (
              //child1 contents here
         ) 
     }
}
Shubham Khatri
  • 270,417
  • 55
  • 406
  • 400
  • Did you get a change to try this approach – Shubham Khatri May 01 '17 at 13:27
  • I didn't understand what **ref={(ip) => {this.child1 = ip}** is supposed to do here, could you please explain? – Mit May 01 '17 at 15:41
  • That is a callback way of declaring refs, – Shubham Khatri May 01 '17 at 15:42
  • Could you please give more details in your code about the ref's part in Child2 and Child1? I also don't understand why you use a ref for Child1 since you are updating it's state through funcUpdateChild1. – Mit May 01 '17 at 16:06
  • You can read about refs here : https://facebook.github.io/react/docs/refs-and-the-dom.html. Also you will need refs as you need to access a function in the child component – Shubham Khatri May 04 '17 at 13:55
0

**Component parent **

   import React from 'react';
    import MM from './modall';
    class App extends React.Component {
        constructor() {
            super();
            this.state = {
                naslov:'',
                telo:''
            };
            this.setStateHandler = this.setStateHandler.bind(this);
            this.postaviStanje = this.postaviStanje.bind(this);
            this.Stanje = this.Stanje.bind(this);
        }
        setStateHandler() {
            this.setState({ naslov: "Naslov Prvi u Modalu", telo:"Novo Prvo telo modala"});

        };
        postaviStanje(){
          this.setState({naslov: " Novi drugi u Modalu", telo:"Novo drugo  telo modala"});
        };
        Stanje(){
          this.setState({naslov: " Novi treci u Modalu", telo:"Novo trece  telo modala"});

        };
        render() {
            return (
                <div>
                    <button onClick = {this.setStateHandler} data-toggle="modal" data-target="#modal">SET STATE</button>
                    <button onClick = {this.postaviStanje} data-toggle="modal" data-target="#modal">SET STATE2</button>
                    <button onClick = {this.Stanje} data-toggle="modal" data-target="#modal">SET STATE3</button>
                    <MM telo={this.state.telo} naslov={this.state.naslov} />)

                </div>
            );
        }
    }
    export default App;

Compnent child

 /**
     * Created by trika on 31-Jan-18.
     */
    import React,{Component} from 'react';

    class Modal extends Component{
        constructor(props) {
            super(props);
            this.state = {
                naslov:this.props.naslov,
                telo: this.props.telo
            };
        }

        render(){

            return(
                <div className="modal" id="modal" role="dialog">
                    <div className="modal-dialog" role="document">
                        <div className="modal-content">
                            <div className="modal-header">
                                <h1 className="modal-title"><strong>{this.props.naslov}</strong></h1>
                                <button type="button" className="close" data-dismiss="modal" aria-label="Close">
                                    <span aria-hidden="true">&times;</span>
                                </button>
                            </div>
                            <div className="modal-body">
                                <p>Modal body text goes here.</p>
                                <h2><strong>{this.props.telo}</strong></h2>
                            </div>
                            <div className="modal-footer">
                                <button type="button" className="btn btn-primary">Save changes</button>
                                <button type="button" className="btn btn-secondary" data-dismiss="modal">Close</button>
                            </div>
                        </div>
                    </div>
                </div>
            );
        }
    }

    export default Modal;
0

Modern Solution with Hook:

1. Parent Component:

const Parent = ({}) => {
  const [child2Data, setChild2Data] = useState(null);
  
  return(
    <view>
      <Child1 child2Data={child2Data} />
      <Child2 setChild2Data={setChild2Data}/>
    </view>
  )
}

1. Child2:

const Child2 = ({ setChild2Data }) => {
  const [data, setData] = useState(null);
  
  const _setData = (_data) => {
    setData(_data)
    setChild2Data(_data)
  }
  
  return(
    <view onClick={() => _setData("Any Data")}>
    </view>
  )
}

1. Child1:

const Child1 = ({ child2Data }) => {
  const [data, setData] = useState(null);

  useEffect(() => {
    setData(child2Data)
  }, [child2Data])
}
Md. Robi Ullah
  • 1,703
  • 3
  • 20
  • 32