状态更新但不呈现

时间:2018-02-12 17:43:42

标签: javascript reactjs

我是ReactJS的新手,并且尝试管理状态更改失败了。初始状态按预期呈现,状态成功更改,但之后元素不会呈现。 DOM控制台中没有任何错误。我已经确保在组件类的构造函数中设置初始状态,并且我也尝试绑定我在构造函数中使用的方法,因为我读过自动绑定不是ES6的一部分。相关的组件代码如下:

class MyComponent extends Component {
    constructor(props) {
        super(props);
            this.state = {
                myIDs: Array(6).fill('0')
        };
        this.getMyIDs = this.getMyIDs.bind(this);

};

componentDidMount() {
    var ids = this.getMyIDs();
    ids.then((result)=> {
        this.setState({ myIDs: result }, () => {
            console.log(this.state.myIDs)
        });
    })

};

componentWillUnmount() {
    this.setState({
        myIDs: Array(6).fill('0')
    });
};

getMyIDs() {
    return fetch('/api/endpoint').then((response) =>{
        return response.json();
    }).then((myIDs) => {
        return myIDs.result
    })
};

render() {
    return (
        <Tweet tweetId={this.state.myIDs[0]} />
        <Tweet tweetId={this.state.myIDs[1]} />
        );
   }
}

export default MyComponent

更新:正在更新的'元素'是来自react-twitter-widgets的'Tweet'组件。它的来源是:

https://github.com/andrewsuzuki/react-twitter-widgets/blob/master/src/components/Tweet.js

export default class Tweet extends React.Component {
  static propTypes = {
    tweetId: PropTypes.string.isRequired,
    options: PropTypes.object,
    onLoad: PropTypes.func,
  };

  static defaultProps = {
    options: {},
    onLoad: () => {},
  };

  shouldComponentUpdate(nextProps) {
    const changed = (name) => !isEqual(this.props[name], nextProps[name])
    return changed('tweetId') || changed('options')
  }

  ready = (tw, element, done) => {
    const { tweetId, options, onLoad } = this.props

    // Options must be cloned since Twitter Widgets modifies it directly
    tw.widgets.createTweet(tweetId, element, cloneDeep(options))
    .then(() => {
      // Widget is loaded
      done()
      onLoad()
    })
  }

  render() {
    return React.createElement(AbstractWidget, { ready: this.ready })
  }
}

2 个答案:

答案 0 :(得分:2)

与React docs一样:

  在安装发生之前调用

componentWillMount()。它是   在render()之前调用,因此同步调用setState()   此方法不会触发额外渲染。一般来说,我们   建议改用构造函数()。

     

避免在此方法中引入任何副作用或订阅。   对于这些用例,请改用componentDidMount()。

你不应该在componentWillMount中使用ajax调用 在里面调用ajax:componentDidMount

另一件事:你为什么要用 componentWillUnmount

该对象将被删除,没有理由在那里进行该调用。

答案 1 :(得分:0)

当前代码中唯一存在的问题是,您返回多个Element组件实例,而不将它们包装在React.Fragment或包装器div的数组中。使用最新版本的react,您必须编写

render() {
    return (
        <React.Fragment>
           <Element Id={this.state.myIDs[0]} />
            <Element Id={this.state.myIDs[1]} />
        </React.Fragment>
        );
   }
}

另外,作为一种做法,您必须在componentDidMount而不是componentWillMount进行异步调用,因为React文档也建议。您可能需要阅读this answer on where write async calls in React了解更多详情

在元素组件中使用prop Id时必须记住的另一件事是componentWillMountcomponentDidMount生命周期函数仅在初始渲染时调用,而不是在此之后,因此,你在Element组件中的其中一个函数中使用this.props.Id,那么你将无法看到更新,因为异步请求的结果只会在稍后出现,请检查this answer如何解决这种情况< / p>