【问题标题】:Why isn't the child component updating?为什么子组件不更新?
【发布时间】:2019-01-22 09:42:23
【问题描述】:

当我更改产品名称时,在本例中是第一个产品,我可以从 App -> List 跟踪更改。但是 list_item 没有更新它的道具。我认为问题在于组件没有重新渲染,但确实如此。就是道具没有更新,不知道为什么。

app.js

import React, { Component } from 'react';

import List from './list';

class App extends Component {
  constructor(props) {
    super(props);

    this.state = {
      products: [
        {
          name: 'TV',
          price: 1000,
          currency: 'USD'
        },
        {
          name: 'SSD',
          price: 100,
          currency: 'USD'
        }
      ],

      name: '',
      price: '',
      currency: ''
    };
  }

  handleChange = event => {
    console.log(`${event.target.name}: ${event.target.value}`);
    this.setState({ [event.target.name]: event.target.value });
  };

  changeState = e => {
    e.preventDefault();
    let products = [...this.state.products];
    products[0].name = this.state.name;
    products[0].price = this.state.price;
    products[0].currency = this.state.currency;

    this.setState({
      products
    });
  };

  render() {
    return (
      <div>
        <button onClick={() => console.log(this.state)}>log</button>
        <List products={this.state.products} />

        <p>{this.state.products[0].name}</p>

        <form onSubmit={this.changeState}>
          Name:
          <br />
          <input
            type="text"
            name="name"
            // defaultValue={this.state.product.name}
            onChange={this.handleChange}
          />
          <br />

          // for simplicity I'm skipping price and currency 
          // but they are there

          <input type="submit" value="Update" />
        </form>
      </div>
    );
  }
}

export default App;

list.js

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

class List extends Component {
  constructor(props) {
    super(props);

    this.state = props;
  }

  render() {
    const productItems = this.state.products.map((product, i) => {
      console.log(product.name);
      return (
        <ListItem
          key={i}
          id={i}
          name={product.name}
          price={product.price}
          currency={product.currency}
        />
      );
    });
    return (
      <table>
        <tbody>
          <tr>
            <th>ID</th>
            <th>Name</th>
            <th>Price</th>
            <th>Currency</th>
            <th>Permissions</th>
          </tr>
          {productItems}
        </tbody>
      </table>
    );
  }
}

export default List;

list_item.js

import React, { Component } from 'react';

class ListItem extends Component {
  constructor(props) {
    super(props);

    this.state = props;
  }

  render() {
    console.log(this.state);
    console.log('rendering');
    return (
      <tr>
        <td>{this.state.id}</td>
        <td>{this.state.name}</td>
        <td>{this.state.price}</td>
        <td>{this.state.currency}</td>
      </tr>
    );
  }
}

export default ListItem;

【问题讨论】:

    标签: reactjs state rerender


    【解决方案1】:

    list_item.js 中的问题是构造函数内部的this.state = props。构造函数只被调用一次,所以状态是在初始化组件时定义的,但从未更新。

    你并不真的需要这个组件中的状态:

    <tr>
            <td>{this.props.id}</td>
            <td>{this.props.name}</td>
            <td>{this.props.price}</td>
            <td>{this.props.currency}</td>
          </tr>
    

    而且因为您不需要状态,所以可以使用无状态组件:

    const ListItem = ({id, name, price, currency}) => (
      <tr>
        <td>{id}</td>
        <td>{name}</td>
        <td>{price}</td>
        <td>{currency}</td>
      </tr>
    );
    

    顺便说一句,list.js 中也有同样的问题,也可能是无状态组件。

    如果你需要从 props 更新你的本地状态,你应该看看 getDerivedStateFromPropscomponentDidUpdate

    但在你的情况下,你不需要。

    【讨论】:

    • 那么,如果我把它做成一个steteless组件应该没问题吧?
    • 是的,肯定会更好。我将添加它作为示例。
    猜你喜欢
    • 2018-04-28
    • 2016-12-17
    • 2019-12-27
    • 2021-05-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多