【问题标题】:State management - Cannot update a component (`Provider`) while rendering a different component状态管理 - 渲染不同组件时无法更新组件(`Provider`)
【发布时间】:2021-10-18 20:38:01
【问题描述】:

我正在尝试使用jotai 来更新全局指标。指标将激活LinearProgress(true or false)

atom.js 中,我创建了一个基本原子作为指标:

export const isDownloadAtom = atom(false)

将提供程序添加到应用程序:

import { Provider } from "jotai";
ReactDOM.render(
<React.StrictMode>
    <Provider>
        <BrowserRouter>
            <App />
        </BrowserRouter>
    </Provider>
</React.StrictMode>,
document.getElementById("root")
);

并最终更新指标:

import { Get } from 'react-axios';
import { useAtom } from "jotai";
import { isDownloadAtom } from "../store/atom";
import Button from '@mui/material/Button';
import Typography from '@mui/material/Typography';


export default function Quotes() {

const [, set] = useAtom(isDownloadAtom)
const url = '/random'

return (
    <div style={{ padding: 20 }}>
        <Get url={url}>
            {(error, response, isLoading, makeRequest, axios) => {
                if (error) {
                    return (<div>Something bad happened: {error.message} <button onClick={() => makeRequest({ params: { reload: true } })}>Retry</button></div>)
                }
                else if (isLoading) {
                    set(true)
                    return (<div>Loading...</div>)
                }
                else if (response !== null) {
                    set(false)
                    return (
                        <div>

还有 LinearProgress 组件:

  import { useAtom } from "jotai";
  import { isDownloadAtom } from "../../store/atom";
  export default function AppBar() {

  const [isDownload] = useAtom(isDownloadAtom)

  return (
    <div >
        <MuiAppBar position="static">
            <Toolbar variant="dense" color="inherit">
                <IconButton
                    edge="start"
                    color="inherit"
                    aria-label="menu"
                    to="/"
                    component={Link}
                    size="large">
                    <IconHome />
                    <Typography variant="h6">Online Information</Typography>
                </IconButton>
            </Toolbar>
            {isDownload ? <LinearProgress /> : ''}
        </MuiAppBar>
    </div>

一般而言,代码可以正常工作,但是当我刷新页面 (F5) 时,我收到以下警告消息

警告:在渲染组件时无法更新组件 (AppBar) 不同的组件(Request)。定位错误的 setState() 调用 在`请求中

我想了解是什么问题以及如何解决。

谢谢

【问题讨论】:

标签: reactjs material-ui jotai


【解决方案1】:

AppBar 和 Quotes 组件的关系是什么?他们是兄弟姐妹还是有条件渲染的?没有看到整个事情就无法真正说出,但我认为渲染块内的setState() 是罪魁祸首。作为一般规则,React 组件不应在渲染期间对其他组件造成副作用。检查直接在&lt;Get&gt; 组件上传递回调是否会改变任何内容。

<Get url={url} onSuccess={(res) => set(false)} onLoading={() => set(true)}>
    {(error, response, isLoading, makeRequest, axios) => {
        if (error) {
            return (<div>Something bad happened: {error.message} <button onClick={() => makeRequest({ params: { reload: true } })}>Retry</button></div>)
        } else if (isLoading) {
            //set(true) - this is probably the issue
            return (<div>Loading...</div>)
        } else if (response !== null) {
            //set(false)
            return (<div>...

如果您能提供一个可重现的最小示例,那么说明发生了什么会容易得多。

【讨论】:

  • 感谢 Jacek 的回答,并对丢失的信息表示歉意。该组件不是兄弟姐妹。它们都来自应用程序的不同部分。我正在添加一个链接,以便您查看关系。 codesandbox.io/s/empty-monad-iid61?file=/src/components/quote/…
  • 您还有问题吗?如果没有端点,我无法确保其正常工作,但 sn-p:&lt;Get url={url} onSuccess={(res) =&gt; set(false)} onLoading={() =&gt; set(true)}&gt; 确实摆脱了不良状态警告。
  • 是的,由于代理问题,该 URL 无法正常工作。最后我决定使用 Redux,我没有任何问题。我认为您的第一个建议(使用回调)是解决此问题的正确途径。我只是想不通如何用jotai做到这一点。非常感谢您的帮助。
猜你喜欢
  • 2020-09-25
  • 1970-01-01
  • 2018-06-05
  • 2023-03-09
  • 2015-04-26
  • 2021-07-05
  • 2021-06-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多