无法更新从JSON生成的子组件的道具

时间:2017-03-22 16:40:14

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

我刚刚开始学习反应,我在尝试更新单个<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;

还有<Option />代码:

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>
    )
  }
}

我希望有人能提供帮助。

2 个答案:

答案 0 :(得分: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

我希望它能解决这个问题。

答案 1 :(得分:0)

感谢alireza的帮助。

我设法解决了这个问题。问题是<Option />收到了太多信息。我删除了所有状态调用,只留下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>
    )
  }
}

然后修改我的有状态组件<StyleOptions />,如下所示

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} />;
    });