score:3

Accepted answer

try to keep you application state at the highest most level in the component tree. the easy way out in this case is to let your table component handle the data state, and also supply event handlers. pass these down as props to the row, and further down as needed. proof of concept: https://jsfiddle.net/dannyjolie/4jfxeag8/1/

the general rule of thumb is to never use component state at all, and leverage all change in application change to the very top most component, but input fields is sometimes an exception from the rule as you may not want to modify the application state while typing.

the basics of it:

export default class table extends react.component {
  constructor(props) {
    super(props);
    this.state.cells = ['foo', 'bar']; // fetch something from your store, or better, pass the cells as props from parent component
    this.handlesubmitevent = this.handlesubmitevent.bind(this);
    this.handlechangeevent = this.handlechangeevent.bind(this);
  }
  handlesubmitevent () {
    // up to date cells are stored in this.state
  }
  handlechangeevent (value, cell) {
    // all values are available in this.state, do with that as you wish :)
  }
  render () {
    ....
    <row handlesubmitevent={this.handlesubmitevent} 
         handlechangeevent={this.handlechangeevent}
         data={this.state.cells} />
    ....
  }
}

score:1

react only pours data changes and, if necessary, re-renders the changed part of dom from top to bottom. what you can do is give a child component access to parent component's state through props:

class parentcomponent extends component {
  handlewhatever(updated) {
    this.setstate({
      whatever: updated
    });
  }

  render() {
    return (
      <childcomponent onedit={::this.handlewhatever} />
    );
  }
}

and

class childcomponent extends component {
  render() {
    return (
      <somethingeditable onchange={this.props.onedit} />
    );
  }
}

so, the idea is:

  1. in parentcomponent, you define a method that, when called, changes this component's state, i.e. parentcomponent's.
  2. in childcomponent, you're having something that is capable of calling a function every time it is changed (the most common example: input element and its onblur event).
  3. every time you change something inside childcomponent, it calls the function that has been passed from parentcomponent, which, in turn, provides data in bottom-to-top direction and delivers it to parentcomponent.
  4. the function is called, bound to parentcomponent, so setstate gets called then, which changes the state of parentcomponent, and it reflects (or not) in re-render of the whole subtree (react takes care of picking only those components that really have to be re-rendered).

this is a classic way to solve the problem of moving data in direction that is opposite to how react expects it to flow.

you can have as many nesting layers as you need, just don't forget to pass that function through all the layers.


Related Query

More Query from same tag