使用SSR初始化React组件状态的最佳方法是什么?

时间:2019-02-21 22:27:03

标签: reactjs serverside-rendering react-props ssr react-state-management

我正在构建一个表,该表需要在某处初始化状态,并且最终通过获取来更新哪些数据。

我的问题是,表需要在服务器端呈现,因此在挂载组件之前需要在服务器上呈现数据,我不能使用componentDidMount。

我可以使用props在render()方法中渲染表内部,但是当表不依赖于通过props而是通过调用api接收数据时,以后如何更新数据呢?

我的结论是我必须使用状态,但是用道具初始化状​​态似乎不行,所以我陷入了困境。

在不违反该规则的情况下,您对组件的初始状态有何建议?

3 个答案:

答案 0 :(得分:1)

我在这里拍: 通过使用默认值初始化状态,让您的组件装载一个空表,并向您的组件添加一个函数,该函数从您说数据应该来自的地方获取。在对您的应用有意义的事件发生时,调用此函数。

让我知道是否,为什么不起作用,以及遇到什么其他问题。

答案 1 :(得分:1)

您可以使用道具初始化状​​态。不会有任何问题。

我的方法是:

  • 保留一个状态变量,并使用props对其进行初始化,以将其呈现在服务器端。
  • 当组件安装在客户端时,将在componentDidMount中调用API。
  • 任何新的道具更改都将在componentWillReceiveProps中进行监视 或静态的getDerivedStateFromProps(取决于您的反应版本)。如果有任何新数据,请更新redux-store(如果您正在使用redux-store)或更新组件状态以使重新渲染显示更新后的数据。

样板:

class Component1 extends React.Component{
  constructor(props) {
    super(props)
    this.state = {
      tableData: props.tableData
    }
  }

  componentDidMount() {
    //Make API call here
    callAPItoGetData()
  }

  componentWillReceiveProps(nextProps) {
    const { tableData } =  nextProps
    if(tableData !== this.state.tableData ) { 
      //You need to make sure that this condition is fullfiled only once to avoid setting state multiple times
      this.setState({
        tableData: nextProps.tableData
      })
      //Alternatively, an action can be dispatched to update the redux-store which will update the props and cause re-render with new data
    }
  }

  render() {
    return (
      <div>{/*render table here*/}</div>
    )
  }
}

希望有帮助。如有任何疑问/困惑,请还原。

答案 2 :(得分:1)

这对于React Hooks和useEffect挂钩是一个很好的例子。根据文档:

  

你可以想到   useEffect Hook作为componentDidMount,componentDidUpdate和   componentWillUnmount组合。

这是一个简单的示例,其中组件首先具有prop数据作为状态,但是一旦API调用完成,它将更改为API数据:

import React, { useState, useEffect } from "react";

function DataList(props) {
  const [users, setUsers] = useState(props.propData);
  useEffect(() => {
    fetch("https://jsonplaceholder.typicode.com/users")
      .then(res => res.json())
      .then(data => {
        setUsers(data);
      });
  });
  return (
    <ul>
      {users.map((user, index) => (
        <li key={index}>{user.name}</li>
      ))}
    </ul>
  );
}

export default DataList;