如何使用componentDidMount调用setState而不引起额外的渲染?

时间:2018-11-10 00:10:19

标签: javascript reactjs

我对componentDidMount有问题:每次在setState中使用componentDidMount时,都会在render中多次调用child components,但我没有知道为什么...看:

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))
  }
}

它给出了: enter image description here

但是,如果我使用ComponentDidUpdate,它将给出: enter image description here

那是正确的,但是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>
    );
  }
}

1 个答案:

答案 0 :(得分:2)

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

第二,您不应将登录用户以纯文本格式存储在本地存储中。取而代之的是,它以及可能的密码应该存储在JWT token(或某种哈希加盐标记)中,或者可能存储在安全的cookie中,然后进行解码并与服务器端进行比较。您当前如何将其设置为localStorage是非常不安全的,任何人都可以简单地设置用户的名字和姓氏以及他们的“用户角色”并获得对其帐户的访问权限。

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