【发布时间】:2021-05-13 11:28:30
【问题描述】:
我正在尝试将 基于类的 组件转换为 功能性 组件。如果我在 useEffect 挂钩中使用 componentDidMount 下的相同代码,则会收到上述错误。
// Class based component
class Container extends Component {
state = {
elements: [],
counter: 1,
bgColor: "#ffffff",
botTextColor: "#000000",
botBGColor: "#aaaaaa",
userTextColor: "#000000",
userBgColor: "#aaaaaa",
};
componentDidMount = async () => {
this.setState({
bgColor: this.props.chat.currentChat.bgColor,
botTextColor: this.props.chat.currentChat.botTextColor,
botBGColor: this.props.chat.currentChat.botBGColor,
userTextColor: this.props.chat.currentChat.userTextColor,
userBgColor: this.props.chat.currentChat.userBgColor,
});
this.setState({
elements:
this.props.chat.currentChat.elements &&
this.props.chat.currentChat.elements.length > 0
? elements
: [
{
id: "0",
data: {
label: (
<WelcomeNode
id={"0"}
images={this.props.chat.media.map((e) => e.file)}
updateChoices={(choices) =>
this.updateChoices("0", choices)
}
updateMessage={(message) =>
this.updateMessage("0", message)
}
updateImage={(e) => this.updateImage(e, "0")}
addEdge={this.addEdgeCustom}
deleteEdgeChoice={(index) =>
this.deleteEdgeChoice("0", index)
}
isChoiceConnected={(index) =>
this.isChoiceConnected("0", index)
}
></WelcomeNode>
),
message: "",
choices: [],
type: "welcome",
id: "0",
},
className: "node-elements",
position: { x: 100, y: 100 },
},
],
counter: elements.length > 0 ? elements.length : 1,
});
}
}
以下是发生错误的功能组件
// Functional component
const initialState = {.....}
const Container = () => {
const [state, setState] = useState(initialState);
const { auth, chat } = useSelector((state) => ({ ...state }));
const dispatch = useDispatch();
const history = useHistory();
useEffect(() => {
setState({
...state,
bgColor: chat.currentChat.bgColor,
botTextColor: chat.currentChat.botTextColor,
botBGColor: chat.currentChat.botBGColor,
userTextColor: chat.currentChat.userTextColor,
userBgColor: chat.currentChat.userBgColor,
});
setState({
...state,
elements:
chat.currentChat.elements && chat.currentChat.elements.length > 0
? elements
: [
{
id: "0",
data: {
label: (
<WelcomeNode
id={"0"}
images={chat.media.map((e) => e.file)}
updateChoices={(choices) => updateChoices("0", choices)}
updateMessage={(message) => updateMessage("0", message)}
updateImage={(e) => updateImage(e, "0")}
addEdge={(e) => addEdgeCustom(e)}
deleteEdgeChoice={(index) =>
deleteEdgeChoice("0", index)
}
isChoiceConnected={(index) =>
isChoiceConnected("0", index)
}
></WelcomeNode>
),
message: "",
choices: [],
type: "welcome",
id: "0",
},
className: "node-elements",
position: { x: 100, y: 100 },
},
],
counter: elements.length > 0 ? elements.length : 1,
});
}, []);
}
引发以下错误并且浏览器崩溃未捕获(在承诺中)错误:重新渲染过多。 React 限制渲染次数以防止无限循环。
【问题讨论】:
-
useEffect 在组件呈现时触发。 setState 触发重新渲染,通过在 useEffect 中调用 setState,您正在创建一个无限循环。
-
感谢回复,请问哪里可以设置状态呢?
-
tbh,我不明白为什么您的状态会跟踪其中的任何元素。看起来这些值都可以通过 useSelector 获得,而您只是将它们复制到状态中。您展示的唯一内容是,如果聊天为空,您正在设置欢迎消息,但这可以在常规渲染过程中(或更多)轻松完成。
-
我刚刚阅读了 useSelector,现在我对你在做什么感到更加困惑。看起来您正在从您的状态创建一个 react redux 选择器,然后您正在尝试从选择器设置状态。这是正确的吗?
-
我正在跟踪另外 10 个状态,因为它会变得太长,所以我没有在此处包括在内,我正在使用 useSelector 访问 redux 商店中可用的状态
标签: reactjs react-hooks use-effect