简体   繁体   English

动态反应更新数组并将其传递给子组件

[英]React updating array dynamically and passing it to child component

I have array in parent component that I need to update dynamically after reading some JSON from api. 我在父组件中有一个数组,在从api中读取一些JSON之后,我需要动态更新它。 I'm using react router and I'm able to pass the array to child component and add a css class based on the array values but I can't seem to figure out how to properly update my array and change array value of panelone to off. 我正在使用React Router,并且能够将数组传递给子组件并基于数组值添加一个CSS类,但是我似乎无法弄清楚如何正确地更新数组并将panelone的数组值更改为关。

Parent component: 父组件:

import React, { Component } from 'react';
import { Route, NavLink, HashRouter } from "react-router-dom";
import Child from './components/Child';

class App extends Component {

  arr = {
    panelone : 'on',
    paneltwo: 'off'
  };

  componentDidMount() {
    // Some function to get JSON... 
      this.arr.panelone = 'off'; // ???
    //...
  }

  render() {

    return (
      <div className="App">
        <TopBar />
        <HashRouter>
          <div>
            <nav>
              <ul className="header">
                <li><NavLink exact to="/">Overview</NavLink></li>
              </ul>
            </nav>
            <div className="main-container">
              <Route 
                exact path="/" 
                render={(props) => <Child arr = {this.arr} />} 
              />
            </div>
          </div>
        </HashRouter>
      </div>
    );
  }
}

Child component: 子组件:

import React, { Component } from 'react';
import { Link } from "react-router-dom";

class Child extends Component {

  render() {

    return (
      <div>
      //This is working OK and css class "on" is added from panelone val
                <div className={'item ' + this.props.arr.panelone}>
                  <p>Some Title</p>
                </div>
            </div>
    );
  }
}

export default Child;

What is the proper way to update arr dynamically and update child components while using react router? 使用React Router时动态更新arr和更新子组件的正确方法是什么?

I would use state for that, then call setState() to update. 我将为此使用状态,然后调用setState()进行更新。 Have you read this: https://reactjs.org/docs/state-and-lifecycle.html#adding-local-state-to-a-class ? 您已阅读以下内容: https : //reactjs.org/docs/state-and-lifecycle.html#adding-local-state-to-a-class吗?

You cannot set or update props directly. 您无法直接设置或更新道具。 I would do something like this: 我会做这样的事情:

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      arr = {
        panelone : 'on',
        paneltwo: 'off'
      }
    };
  }

  componentDidMount() {
    this.setState({
      arr: {
        ...this.state.arr,
        panelone: 'off'
      }
    });
  }

That arr is actually a instance field object, so the right way to access it and update it is through this keyword: arr实际上是一个实例字段对象,因此访问和更新它的正确方法是通过this关键字:

componentDidMount() {
  // Some function to get JSON... 

  this.arr = {panelone: 'off', paneltwo: 'on'}

  //...
}

But that would leave you with the problem that React doesnt update child components when you update custom instance fields. 但这将给您带来以下问题:更新自定义实例字段时,React不会更新子组件。

So the right way will be using the component's state. 因此正确的方法将是使用组件的状态。 At the beginning App 's class define the state with arr inside: App的类的开头,用arr定义状态:

constructor(props) {
  super(props);

  this.state = {
    arr: {
      panelone: 'off', paneltwo: 'on'
    }
  };
}

Then instead of updating arr as an instance field you should use setState method: 然后,应该使用setState方法而不是将arr作为实例字段更新:

componentDidMount() {
  // Some function to get JSON... 

  this.setState({
    arr: {
      panelone: 'off', 
      paneltwo: 'on'
    }
  });

  //...
}

In the render method of App use this.state.arr instead of this.arr : App的render方法中,使用this.state.arr代替this.arr

render() {
    return (
      <div className="App">
        <TopBar />
        <HashRouter>
          <div>
            <nav>
              <ul className="header">
                <li><NavLink exact to="/">Overview</NavLink></li>
              </ul>
            </nav>
            <div className="main-container">
              <Route 
                exact path="/" 
                render={(props) => <Child arr = {this.state.arr} />} 
              />
            </div>
          </div>
        </HashRouter>
      </div>
    );
}

And it will just work the way you are currently doing with the Child component, you should check state documentation 而且它将仅以您当前使用Child组件的方式工作,因此您应该查看状态文档

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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