首页 > 解决方案 > 仅在刷新页面后获取令牌。刷新前token返回null

问题描述

在我尝试调用两个函数的组件Items中。componentDidMount ()从 localStorage 获取domain-> 将域返回给我 -> 没关系。从 localStorage 获取时,token返回 me null。只有当我刷新页面时,它才会获得令牌值。

登录

class Login extends Component {
  constructor (props) {
    super(props);
    this.state = {
      email: '',
      password: '',
      token: JSON.parse(localStorage.getItem("token"))
    }
  }

  onSubmit = (event) => {
    event.preventDefault();

    axios({ 
      method: 'post', 
      url, 
      data, 
      config
    }) 
      .then(res => { 
        const instanceSingle = res.data.instances.map((instance, index) => {
          return instance.domain
        });
        if (res.status === 200) {
          this.setState({
            instances: res.data.instances
          }, this.getDomain(instanceSingle))
        } 
      }).catch(err => { 
        console.log(err);
      });
  }

  getDomain = (domain) => {

    localStorage.setItem('domain', domain);

    this.getToken();
  }

  getToken = () => {

    const domain = localStorage.getItem('domain');
    const url = '${domain}/oauth2/token';

    axios({ 
      method: 'post', 
      url, 
      data, 
      config
    }) 
      .then(res => { 
        if (res.status === 200) {
          localStorage.setItem('token', JSON.stringify(res.data['access_token']))     
        } 
      }).catch(err => { 
        console.log(err);
      });

  }


  render () {
    const {instances} = this.state;

    return (
      <div>
        {this.state.token || instances.length === 1 ?
          <Items
            token= {JSON.parse(localStorage.getItem("token"))}
            domain={localStorage.getItem('domain')}
            instances={this.state.instances}
          />
          :
           instances.length > 2 ?
            <AnotherComponent      
            />
            :
            <form method="post" onSubmit={this.onSubmit}>
                            <input type="email"
                                value={this.state.email}
                            />
                            </div>
                            <input type="password" className="form-control" name="password"
                                    value={this.state.password}
                                    onChange={this.handleUserInput}  />
                            </div>
                            <button type="submit">Log in</button>          
            </form>    
        }
      </div>
    )
  }
}

项目

class Items extends Component {
  constructor (props) {
    super(props);
    this.state = {
      items: []
    }
  }

  componentDidMount() {
    const token = JSON.parse(localStorage.getItem('token'))
    const domain = localStorage.getItem('domain');

        axios({
            url: `${domain}/api/v1/items`,
            method: "GET",
            headers: {
                'Authorization': `Bearer ${token}`
            }
        })
        .then(response => {
            this.setState({
                items: response.data
            });
            this.function2();
            this.function1();
        })
        .catch(error => {
            console.log(error);
        })
    }

    render () {
            return (
                <div>
                    {this.state.items.map((item, index) => 
                            <Item

                            />
                    )}    
                </div>
            )
    }
}

标签: javascriptreactjs

解决方案


我有三个选择,只需尝试一下:

  1. 您在调用登录后设置了实例,这意味着在您更改状态时做出反应,渲染将在状态更改后自动调用。这就是为什么this.state.token || instances.length === 1即使令牌未设置为状态也会执行您的第二个或条件的原因。并且您的子组件没有从 Login 组件获取令牌值作为道具
  2. 您已经为 Items 和另一个组件使用了条件组件渲染,这就是为什么它总是安装,即使只有实例字段会在状态中发生变化,这就是为什么同时设置您的instancestoken状态而不是两者都在不同的行。
  3. 如果你不想让你的代码失败,那就放 && 而不是 || 因为从您的代码实例中获得价值,但令牌没有获得价值。并且根据您在 componentDidMount 中的代码,您必须需要令牌,然后为什么要冒令牌的风险变得空,只需放置&&而不是||.

推荐阅读