ReactJS-道具和组件不同步

时间:2019-12-04 15:54:35

标签: javascript reactjs redux

我正在使用前端的ReactJS和Redux在Web应用程序上工作,并且看到组件的行为“不同步”-子组件(从父组件接收道具)正在呈现,然后再接收道具。结果,子组件在接收数据之前在第一次渲染期间抛出错误,因为此时的props尚未定义。

换句话说:

组件A通过Redux和状态接收用户的数据,并将其传递给组件B进行显示。当组件B首先渲染时,它不读取组件A通过的道具,并且会引发错误。但是,如果我们不尝试渲染道具数据,而只是将数据记录到控制台,我将看到组件B重新渲染3次,其中第一次定义道具是未定义的,而第二次和第三次道具都已接收并且所有数据存在。

我如何确保在渲染之前已收到所有道具,以确保组件B在渲染之前已收到道具?

组件A

import React from 'react';
import { connect } from 'react-redux';
import B from './B';

const A = ({ user }) => {
   return (
      <B user={user} />
   )
}

A.propTypes = {
   user: PropTypes.object
}
const mapStateToProps = state = ({ user: state.user });
export default connect(mapStateToProps)(A);

组件B

import React from 'react';

const B = props => {
   const user = props.user;
   const username = user.username;
   return (
      <div>
         {username}  // throws an error on render, as props.user is undefined
      </div>
   )
}

export default B;

我尝试使用useEffect来加载道具,但是即使使用useEffect仍然会发生此错误。我之所以不在组件A中嵌套组件B是因为我也有使用组件B作为数据容器的组件C(公共组件)。

关于如何解决这种“不同步”渲染的想法吗?


找到解决方案! 我更新Redux状态的方式存在一个小问题,并为组件A添加了加载障碍,以确保在渲染组件A(组件B嵌套在其中)之前全部加载完毕。

组件A

import React from 'react';
import { connect } from 'react-redux';
import B from './B';

const A = ({ user, loaded }) => {
   if (!loaded) {
      return "Loading"
   }
   return (
      <B user={user} />
   )
}

A.propTypes = {
   user: PropTypes.object,
   loaded: PropTypes.bool
}
const mapStateToProps = state = ({ user: state.user, loaded: state.user.loaded });
export default connect(mapStateToProps)(A);

用户Redux文件

const initState = { username: "", email: "", phone: "" }
export default (state=initState, action) {
   switch (action.type) {
      case "LOAD":  
         state.username = action.data.username;
         state.email = action.data.email;
         state.phone = action.data.phone;
         return { ...state }  // error was original here, where I was setting return to state: action.data
      case "ERR":
         return { username: "", email: "", phone: "" }
      default:
         return state;
   }
}

2 个答案:

答案 0 :(得分:0)

问题是用户在A的第一次渲染时也是null / undefined,所以这正是它传递给B的原因,因此是错误的。

您要做的就是在返回B之前检查用户是否存在,否则返回null

import React from 'react';
import { connect } from 'react-redux';
import B from './B';

const A = ({ user }) => {
   if(!user)
       return null;
   return (
      <B user={user} />
   )
}

A.propTypes = {
   user: PropTypes.object
}
const mapStateToProps = state = ({ user: state.user });
export default connect(mapStateToProps)(A);

答案 1 :(得分:0)

您是否尝试过使用if / then语句?喜欢:

import React from 'react';

const B = props => {
  if (props.user && typeof props.user.username !== "undefined"){
    const user = props.user;
    const username = user.username;
    return (
      <div>
        {username}  // throws an error on render, as props.user is undefined
      </div>
    )
  } else{
    'Loading'
  }
}

export default B;