Redux或setTimeout - 如何在子组件中观看道具更改?

时间:2017-06-28 19:39:45

标签: javascript reactjs redux settimeout

我有App组件,它从服务器加载JSON数据。 加载数据后,我更新子组件的状态。

现在我的功能看起来像这样:

componentDidMount() {
  setTimeout(()=> {
    if (this.state.users.length !== this.props.users.length) {
      this.setState({users: this.props.users});
      this.setState({tasks: this.getTasksArray()});
  }, 500);
}

我使用setTimeout等待数据被加载并发送给子节点。但我敢肯定,这不是最好的方式 可能是,最好使用redux而不是setTimeout。

父组件加载数据:

componentWillMount() {
  var _url = "/api/getusers/";
  fetch(_url)
  .then((response) => response.json())
  .then(users => {
    this.setState({ users });
    console.log("Loaded data:", users);
  });
}

父发送道具:

<AllTasks users={this.state.users} />

所以,我的问题是:观察子组件变化的最佳方法是什么? 我的意思是在这种特殊情况下。

2 个答案:

答案 0 :(得分:2)

是的,这不是正确的方法,因为api调用将是异步的,我们不知道需要花多少时间。

因此,不要使用_this.function1 is not a function ,而是在子组件中使用setTimeout生命周期方法,只要更改componentWillReceiveProps值(父组件的状态),就会调用它。

像这样:

props

还有一件事,不要在函数内多次调用componentWillReceiveProps(newProps){ this.setState({ users: newProps.users, tasks: this.getTasksArray() }) } 因为setState会触发重新渲染,所以首先执行所有计算,然后在最后执行setState并在一次通话中更新所有值。

根据 DOC

  

在安装的组件之前调用componentWillReceiveProps()   收到新的道具。如果您需要更新状态以响应   prop更改(例如,重置它),您可以比较this.props   和nextProps并使用this.setState()执行状态转换   这种方法。

<强>更新

您正在使用setState方法调用方法并使用该方法中的cWRP值,props将仅在此生命周期方法之后具有更新的值。因此,您需要将newProps值作为参数传递到此this.props中,并使用该值代替function

像这样:

this.props

查看此答案以获取更多详细信息:componentWillRecieveProps method is not working properly: ReactJS

答案 1 :(得分:0)

我发现了问题。

我有getTasksArray()函数,它依赖于props并使用this.props.users。 所以,当我像这样更新状态时:

# Extracted from package ---------------------------------------------------
object <- mod.mswm
(swi   <- object@switch[-length(object@switch)])
(np    <- object["k"]*sum(swi)+sum(!swi))

(AIC=2*object["Fit"]["logLikel"]+2*np)
#[1] 637.0736
(BIC=2*object["Fit"]["logLikel"]+2*np*log(nrow(object@model$model)))
#[1] 693.479

getTasksArray()函数使用空数组。 但当我将它分成2行并添加setTimeout(fn,0)时:

this.setState({
  users: newProps.users, 
  tasks: this.getTasksArray()
})

getTasksArray()函数使用已更新的数组。 setTimeout(fn,0)使getTasksArray()在所有其他之后运行(即使我将超时设置为0 ms)。

以下是没有setTimeout的console.log的屏幕截图: enter image description here 这是使用setTimeout的屏幕截图: enter image description here