首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >不变违反:App(.)渲染没有返回任何内容。

不变违反:App(.)渲染没有返回任何内容。
EN

Stack Overflow用户
提问于 2018-05-16 14:32:47
回答 3查看 1.7K关注 0票数 1

我试图根据AsyncStorage的承诺来呈现组件,并得到了以下错误:

异常:不变冲突:App(.):render没有返回任何内容。这通常意味着缺少返回语句。或者,若要不呈现任何内容,请返回null。

我知道组件是好的,因为我试着单独呈现每个组件,它们都工作得很好,当我试图通过AsyncStorage.getItem渲染它时,我无法完成它。

代码:

代码语言:javascript
代码运行次数:0
运行
复制
checkToken = () => {
    AsyncStorage.getItem('user')
        .then((res) => {
            res = JSON.parse(res)
            console.log('this is checkToken()',res.token)
            // this.renderUserSection(res.token);
            return res.token;   
        })
        .then((token) => {
          return (
             <View style={styles.container}> 
                {!token ? this.renderUser() : this.renderApp()} 
             </View>
          )  
        })
        .catch((err) => {
          console.log(err)
        })
}



render() {
    return (
        this.checkToken() 
    ) 
}

当我这么做的时候

代码语言:javascript
代码运行次数:0
运行
复制
render() {
    return (
        this.renderUser() 
    ) 
}

效果很好!

也是当我这么做的时候

代码语言:javascript
代码运行次数:0
运行
复制
render() {
    return (
        this.renderApp() 
    ) 
}

它也起作用了,所以功能是好的,是逻辑,或者是我无法让它工作的最上面的逻辑。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2018-05-16 14:42:51

AsyncStorage是异步的,所以它不会立即返回您编写的视图。在AsyncStorage检索到数据之前,您需要显示一个旋转器或自定义视图。

这里有一个解决方案:

代码语言:javascript
代码运行次数:0
运行
复制
constructor() {
    this.state = {
        token: null
    }
    this.checkToken();
}

checkToken = () => {
    AsyncStorage.getItem('user')
    .then((res) => {
      res = JSON.parse(res)
      console.log('this is checkToken()',res.token)
      // this.renderUserSection(res.token);
    })
    .then((token) => {
        this.setState({token: token})  
    })
    .catch((err) => {
      console.log(err)
    })
}

render() {
    if (this.state.token == null) {
       return (<View> {this.renderUser()} </View>)
    }
    else {
        return (
            <View style={styles.container}> 
               {this.renderApp()}
            </View>
        )
    }
}
票数 2
EN

Stack Overflow用户

发布于 2018-05-16 14:42:28

嗯,checkToken是一个函数,它:

  • 调用AsyncStorage
  • 返回未定义

因此,如果日志告诉您渲染不返回任何内容,则日志是正确的!

您应该向您的checkToken添加一个返回语句。

那么我想我们应该进入第2部分,现在检查令牌是一个函数,它:

  • 调用AsyncStorage
  • 返回已执行的函数将被返回的承诺。

它不太管用..。反应呈现组件,而不是承诺!

我的看法是,你需要重构这是如何工作的。我的建议:

  • 将checkToken重构为一个函数,如果getItem成功,则调用setState({ content:})
  • 如果失败,setState({ content: null })
  • 在render函数中,不要返回函数调用。相反,返回state.content
  • 如果要在每次呈现时检查令牌,请在从RENDER返回checkToken之前调用state.content。
  • 如果您只想检查令牌一次,请调用componentDidMount中的componentDidMount-或任何您需要的地方。

这是我认为代码应该是什么样子的示例。您应该考虑一下叫checkToken的最佳位置是什么。

代码语言:javascript
代码运行次数:0
运行
复制
  checkToken = () => {
    let self = this;
    AsyncStorage.getItem('user')
    .then((res) => {
      res = JSON.parse(res)
      console.log('this is checkToken()',res.token)
      // this.renderUserSection(res.token);
      return res.token;   
    })
    .then((token) => {
      self.setState({
        content: (<View style={styles.container}> 
          {!token ? self.renderUser() : self.renderApp()} 
        </View>)
      });
    })
    .catch((err) => {
      self.setState({ content: null })
      console.log(err)
    })
  }
render() {
  //are you sure you need to call checkToken here? Maybe there's a better place? if there is no shouldComponentUpdate this could cause an infinite re-render loop
  //you could maybe call it for componentDidMount, or some other lifecycle method?
  //otherwise I think you'll need that shouldComponentUpdate implementation.
  this.checkToken();
  return this.state.content;
}
票数 0
EN

Stack Overflow用户

发布于 2018-05-16 14:43:26

请先使用状态来存储令牌。(您拥有的“checkToken”方法是一个空方法)

代码语言:javascript
代码运行次数:0
运行
复制
checkToken = () => {
        AsyncStorage.getItem('user')
        .then((res) => {
          res = JSON.parse(res)
          console.log('this is checkToken()',res.token)
          // this.renderUserSection(res.token);
          return res.token;
          this.setState(state => ({
            ...state,
            token : res.token
          }))
        })
        .catch((err) => {
          console.log(err)
        })
      }

      render () {
        const { token } = this.state;
        return (
          <View style={styles.container}> 
              {
                !token 
                  ? this.renderUser() 
                  : this.renderApp()
               } 
          </View>
        )
      }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50373673

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档