【问题标题】:How to call setState with componentDidMount without causing extra calls to render?如何使用 componentDidMount 调用 setState 而不会导致额外的渲染调用?
【发布时间】:2019-04-13 13:30:04
【问题描述】:

我对@9​​87654326@ 有疑问:每次我在componentDidMount 中使用setState 时,它都会在child components 中多次调用render,我不知道为什么......看:

componentDidMount() {
  const firstName = localStorage.getItem('nameLoggedUser');
  const lastName = localStorage.getItem('lastNameLoggedUser');
  const fullName = `${firstName} ${lastName}`.toLowerCase();

  const loggedUserIs = localStorage.getItem("user-role");
  const emailLoggedUser = localStorage.getItem('emailLoggedUser');

  if (loggedUserIs === 'full') {
    axios.get(`/api/menuDomain`)
      .then(res => this.setState({
        domain: res.data
      }))
      .catch(err => console.log(err))
  }
}

它给出了这个:

但是,如果我使用ComponentDidUpdate,它会给出:

没错,但是 AJAX 调用没有发生...

我想进行 AJAX 调用,而不是让它渲染多次...但我不知道如何...有人可以帮助我吗?请问???

我也在使用react-router

    return (
      <Router>
        <Switch>
          <Route path="/login" component={Login} />
          <Route exact path="/" render={() =>
            <Overview
              {...myProps}
            />
            } 
            />

          <Route path="/list" render={() =>
            <Graphic
              {...myProps}
            />
          } />
        </Switch>
      </Router>
    );
  }
}

【问题讨论】:

标签: javascript reactjs


【解决方案1】:

首先,永远不要将你的路由包装在有状态的组件中。相反,路由应该是一个无状态函数,只返回相同的 JSX 路由元素。对于上面的示例,您应该使用 HOC 来包装您的受保护路由并且只关注身份验证:https://stackoverflow.com/a/53197429/7376526

其次,您不应将已登录的用户以纯文本形式存储在本地存储中。相反,它和可能的密码应该存储在JWT token(或某种散列加盐分的令牌中)或可能存储在安全 cookie 中,然后解码并与服务器端进行比较。您当前如何将其设置为 localStorage 非常不安全,任何人都可以简单地设置用户的名字和姓氏及其“用户角色”并获得对其帐户的访问权限。

第三,每个container 应该处理和获取相关数据并将其传递给相关的component 进行显示。为了提高性能,您应该将检索到的数据划分为该特定组件的相关数据。由于您有多个路线,因此一次获取所有内容是浪费的。例如,在FetchOverview 容器的componentDidMount 中获取Overview 数据,然后将其传递给DisplayOverview 子组件进行显示。阅读本文以获取有关containerscomponents 的更多信息:https://medium.com/@dan_abramov/smart-and-dumb-components-7ca2f9a7c7d0

【讨论】:

  • 朋友你好,好吗??我喜欢你的回答!!我要制作,但我有一个问题...我可以使用 ComponentWillReceiveProps 制作 componentFetching 吗?即在收到新道具时发出请求???
  • 要么使用 componentDidUpdate(prevProps,prevState) 并进行某种 propstate 比较以更新数据(componentWillReceiveProps 已弃用)或创建 handleOnClickmethod 已通过向下到子级的onClick 事件处理程序——这应该只是触发父级的state 中的更新(例如,进行另一个AJAX 调用),其中state 得到更新并传递回给子级。理想情况下,父节点保持有状态,子节点保持无状态;但是,孩子可以调用父方法来更新父母的状态。
  • 此外,如果您担心“还没有要显示的数据,如何显示微调器?”,那么您将需要使用条件渲染:codesandbox.io/s/zm3mqw2m4(参见容器/SimpleForm.js 是条件渲染的示例——我在render 方法中使用并与isLoading 进行比较以显示微调器或显示表单)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-19
  • 2019-08-14
  • 2020-07-16
相关资源
最近更新 更多