1

Am new to React, I like to maintain state in parent component itself and pass the same to all child components on child component I would like to update the child state from the parent component state am using getDerivedStateFromProps to update it. But i guess am doing it wrong as the values are updated in inner level object like inside state there is a level object named state, I had tried to spread it as well but it didn't work.

Parent Component

  import React from 'react';
  import './App.css';
  import Navbar from './components/Navbar';

  class App extends React.Component {
    state = {
      name: 'Kannan',
      countryCode: '',
      mobile: '',
      isModalOpen: false,
    };

    render() {
      return (
        <div className="App">
          <Navbar params={this.state}></Navbar>
        </div>
      );
    }
  }

  export default App;

Child Component

  class NavbarComponent extends React.Component {
  constructor(props) {
    super(props);

    console.log(props.params);

    this.state = {};
  }

  static getDerivedStateFromProps(props, state) {
    console.log(state);
    return { state: props.params };
    // return  {state: { ...props.params }} ;
  }

  render() {
    console.log(this.state);
    return (
      <div>
           "Something"
      </div>
    );
  }
}

I have tried with { state: ...props.params} and also {state: props.params} in the render console.log am getting

   {state: {…}}
     state: {name: "Kannan", countryCode: "", mobile: "", isModalOpen: false}
    __proto__: Object

what am expecting is

 state: {name: "Kannan",countryCode:"",mobile:"",isModalOpen:false}

Note: No REDUX. I don't want to use REDUX If there is any other better approach to update child component state? Also, I would like to know whether maintaining state for each child component is a good practice or not? Any help is appreciated

Kannan T
  • 1,639
  • 5
  • 18
  • 29
  • Why does the child need state at all? Can it not just use props? – Nicholas Tower Sep 23 '19 at 19:29
  • Yes we can but I would like to try with child state is it wrong approach? – Kannan T Sep 23 '19 at 19:30
  • Trying to duplicate props into state is almost always the wrong approach. Have the parent component be the single source of truth. It will have the value in its state, and then all other components will get the value via props. – Nicholas Tower Sep 23 '19 at 19:31
  • @NicholasTower Am going to have multiple child component under Navbar component which is child component of APP component shall i still have the state only in APP component? – Kannan T Sep 24 '19 at 06:52
  • Do you have one set of data which all the components base themselves off of? Then put the state in the parent, pass it as props, and don't duplicate it. Does each child have independent sets of data? Then *remove* state from the parent, don't pass it as props, and have each child do their own thing. It is very rare that taking in props and duplicating it to state is the right approach. Please read this article: https://reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html – Nicholas Tower Sep 24 '19 at 10:04
  • @NicholasTower Mine is bit of both I have few data’s like contact details which I need on the main parent component as well inner child component few data I need only on child component, for example am writing navbar as child component in navbar component am writing modal component as child component which have its own data like when to open the modal or to close same goes with navbar component as well which has own data what has to be happened when I click navbar buttons, Remember I need contact details from parent component so can you tell me a good approach in my case – Kannan T Sep 24 '19 at 13:36
  • Nothing you have described requires duplicating props to state. Use the standard react approach: For a given piece of data, keep it as state in the parent component (or whatever component is the common ancestor of the components that need that data). Then use props to pass it down to any components that need it. – Nicholas Tower Sep 24 '19 at 13:44
  • 1
    You may find this article a useful introduction: https://reactjs.org/docs/lifting-state-up.html – Nicholas Tower Sep 24 '19 at 13:47
  • @NicholasTower thanks man I’ll check it out and get back to you if I have any queries – Kannan T Sep 24 '19 at 13:48

2 Answers2

1

Well I would suggest to use redux instead of passing the whole state from Parent to child. But if you really wanna do this then it should be like below:

import React from 'react';
import './App.css';
import Navbar from './components/Navbar';

**Parent Component**

class App extends React.Component {
  state = {
    name: 'Kannan',
    countryCode: '',
    mobile: '',
    isModalOpen: false,
  };

  render() {
    return (
    <div className="App">
        <Navbar params={this.state}></Navbar>
    </div>
    );
  }
}

export default App;

**Child Component**

class NavbarComponent extends React.Component {
  static getDerivedStateFromProps(props, state) {
    return { ...props.params };
  }

  constructor(props) {
    super(props);
    this.state = props.params;
  }

  render() {
    return (
      <div>
        <span>"Something"</span>
      </div>
    );
  }
}
Milind Agrawal
  • 2,724
  • 1
  • 13
  • 20
1

Instead of

static getDerivedStateFromProps(props, state) {
    return { state: props.params };
}

Try

  static getDerivedStateFromProps(props, state) {
    return props.params;
  }

In the first piece of code, you're passing an object with a key state, and your child component will have it's state set to {state: whateverCameFromAnotherComponent} as you mention in "inside state there is a level object named state". If you just pass the state from your parent as you receive it, the child's state should be the very same as the parent's.

I tried to recreate your scenario here:

Edit heuristic-shtern-7ukg9

and as you can see, the Navbar's state is set to Object {name: "Kannan", countryCode: "", mobile: "", isModalOpen: false}, without the state key in it.

Elder
  • 1,475
  • 9
  • 17