【问题标题】:Can't update props of child components generated from JSON无法更新从 JSON 生成的子组件的 props
【发布时间】:2017-08-14 22:16:34
【问题描述】:

我刚开始学习 react,但在尝试更新单个 <Option /> 子元素的状态时遇到了麻烦。

我的 Flux Store 正在发出变化,在 React devtools 中我可以看到 StyleOptions 元素的状态正在更新,但它不会更新子组件<Option />

我怀疑这是因为我将选项列表保存在一个变量中。

我需要使用这个,因为我从 JSON 中提取了这个选项。

const Options = this.state.options.map((parent) => {
        const children = parent.children.map((child) => {
          return (
            <Option {...child} />
          )
        });
        return <Option {...parent} children={children} />;
    });

所以我认为这部分可能会导致问题。

我来自OptionsStore 的示例数据如下所示。

this.options = [
      {
        key: "suitType",
        label: "Suit Type",
        selected: false,
        children: [
          {
            key: "suittype_skinny",
            parent: "suitType",
            label: "Skinny",
            price: "£50",
            description: "Short description",
            images: {
              general: "http://placehold.it/600x600",
              closeUp: "http://placehold.it/620x620",
              thumbnail: "http://placehold.it/100x100",
            },
            selected: false,
          },
          {
            key: "suittype_wedding",
            parent: "suitType",
            label: "Wedding",
            price: "£50",
            description: "Short description",
            images: {
              general: "http://placehold.it/600x600",
              closeUp: "http://placehold.it/620x620",
              thumbnail: "http://placehold.it/100x100",
            },
            selected: false,
          }
        ]
      }
    ]

子道具也没有改变。

完整代码在这里:

import React, { Component } from 'react';
import Option from './Option';
import OptionsStore from '../../stores/OptionsStore';

class StyleOptions extends Component {
  constructor(props) {
    super(props)
    this.state = {
      options: OptionsStore.getAllItems(),
    }
  }
  componentDidMount() {
    OptionsStore.on('change',(e) => {
      this.setState({
        options: OptionsStore.getAllItems(),
      });
      console.log('optionsStore received an update');
    });
  }
  render() {
    const Options = this.state.options.map((parent) => {
        const children = parent.children.map((child) => {
          return (
            <Option {...child} />
          )
        });
        return <Option {...parent} children={children} />;
    });
    return(
      <div className="col-xs-6">
        <ul className="list-group">
          {Options}
        </ul>
      </div>
    )
  }
}

export default StyleOptions;

还有&lt;Option /&gt; 代码:

import React, { Component } from 'react';

export default class Option extends Component {
  constructor(props) {
    super(props);
      this.hasChildren = this.props.children ? true : false;
      this.hasThumb = this.props.images ? true : false;
      this.children = this.state.children;

    this.state = {
      label: this.props.label,
      description: this.props.description,
      selected: false,
      price: this.props.price
    }
  }
  render() {
    return (
      <li className={this.hasChildren ? 'list-group-item':'col-sm-4 list-group-item' } selected={this.state.selected}>
          <a className="media">
            {this.hasThumb ? (
            <div className="media-left media-middle">
              <img src={this.props.images.thumbnail} alt={this.state.label} />
            </div>
            ) : (
              ' '
            )}
            <div className="media-body">
              <h4 className="option-name">{this.state.label}</h4>
              <p className="info">{this.state.description}</p>
              <span className="text-success pricing">{this.state.price}</span>
            </div>
          </a>
          {this.hasChildren ? (
              <ul className="panel-body">
                  {this.children}
              </ul>
            ) : (
              ' '
            )}
      </li>
    )
  }
}

希望有人能帮忙。

【问题讨论】:

    标签: json reactjs ecmascript-6 flux reactjs-flux


    【解决方案1】:

    问题出在您的 Option 组件内部。 您定义 this.children = this.state.children 。之后,您定义了初始状态,但没有“孩子”。这样子状态就没有定义了。

    首先,将children: this.props.children 添加到您的状态中。

    然后,改变

    {this.hasChildren ? (
                  <ul className="panel-body">
                      {this.children}
                  </ul>
                ) : (
                  ' '
    )}
    

    {this.hasChildren ? (
              <ul className="panel-body">
                  {this.state.children}
              </ul>
            ) : (
              ' '
    )}
    

    并且不需要定义this.children = this.state.children

    希望能解决问题。

    【讨论】:

      【解决方案2】:

      感谢 alireza 的帮助。

      我设法修复它。问题是&lt;Option /&gt; 收到了太多信息。我删除了所有状态调用,只留下了下面的 if 语句。

      import React, { Component } from 'react';
      
      export default class Option extends Component {
        constructor(props) {
          super(props);
            this.hasChildren = this.props.children ? true : false;
            this.hasThumb = this.props.images ? true : false;
            //this.state = this.props;
        }
        render() {
          return (
            <li className={this.hasChildren ? 'list-group-item':'col-sm-4 list-group-item' }>
                <a className="media">
                  {this.hasThumb ? (
                  <div className="media-left media-middle">
                    <img src={this.props.images.thumbnail} alt={this.props.label} />
                  </div>
                  ) : (
                    ' '
                  )}
                  <div className="media-body">
                    <h4 className="option-name">{this.props.label}</h4>
                    <p className="info">{this.props.description}</p>
                    <span className="text-success pricing">{this.props.price}</span>
                  </div>
                </a>
                {this.hasChildren ? (
                    <ul className="panel-body">
                        {this.props.children}
                    </ul>
                  ) : (
                    ' '
                  )}
            </li>
          )
        }
      }
      

      然后修改我的有状态组件&lt;StyleOptions /&gt;,如下所示

      import React, { Component } from 'react';
      import Option from './Option';
      import OptionsStore from '../../stores/OptionsStore';
      
      class StyleOptions extends Component {
        constructor(props) {
          super(props)
          this.state = {
            options: OptionsStore.getAllItems(),
          }
        }
        componentWillMount() {
          OptionsStore.on("change", () => {
            this.setState({
              options: OptionsStore.getAllItems(),
            });
            console.log('optionsStore received an update');
          });
        }
        render() {
          const { options } = this.state;
          const allOptions = options.map((option) => {
              const { children } = option;
              const optionChildren = children.map((child) => {
                return <Option {...child} />;
              })
              return <Option {...option} children={optionChildren} />;
          });
          return(
            <div className="col-xs-12">
              <ul className="list-group">
                {allOptions}
              </ul>
            </div>
          )
        }
      }
      
      export default StyleOptions;
      

      不确定为什么它现在可以正常工作。我怀疑它可能已经改变了,因为我稍微修改了地图。

      旧的/破损的

      const Options = this.state.options.map((parent) => {
              const children = parent.children.map((child) => {
                return (
                  <Option {...child} />
                )
              });
              return <Option {...parent} children={children} />;
      });
      

      新的/正在工作的

          const { options } = this.state;
          const allOptions = options.map((option) => {
              const { children } = option;
              const optionChildren = children.map((child) => {
                return <Option {...child} />;
              })
              return <Option {...option} children={optionChildren} />;
          });
      

      【讨论】:

        猜你喜欢
        • 2019-06-11
        • 2018-06-08
        • 1970-01-01
        • 1970-01-01
        • 2021-08-20
        • 2020-12-10
        • 1970-01-01
        • 2021-10-09
        • 1970-01-01
        相关资源
        最近更新 更多