我正在使用前端的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;
}
}
答案 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;