复杂条件渲染的反应方式是哪种?

时间:2018-06-18 01:03:35

标签: reactjs

问题

我遇到组件的条件渲染问题。据我所知,有两种方法可以做到这一点。第一种方法是丑陋的,因为当我不得不做多个&&和条件。第二种方法很清楚,但它将组件本身添加到状态,并且使用状态值进行进一步计算是困难的。例如,检查错误的消息值是什么。

我已经给出了以下两种方法。请让我知道哪个更好。是否有另一种方法而不是两种方法?

应用

这是一个简单的应用程序,可以呈现' Main'组件或' Err'组件,基于“错误”的状态。第一种方法中的属性和第二种方法中的comp属性的内容。

最初呈现主要组件。 err属性在2秒后更新为某个值,从而触发重新渲染。这时,我想要渲染Err组件。

真正的应用程序是我在componentDidMount上有一个外部api调用,它可能会失败或成功。我必须根据结果显示不同的组件。更新多个状态值会稍微复杂一些。为了演示,我简化了下面的问题。

两种类型的常用步骤

npx create-react-app react-oop

组件/ Err.js

import React,{Component} from 'react'

class Err extends Component {
    render(){
        return(
            <div>
                Error Component
            </div>
            )
    }
}

export default Err

组件/ Main.js

import React, {Component} from 'react'

class Main extends Component {
    render(){
        return( 
            <div>
                Main Component
            </div>
        )
    }
}

export default Main
  

第一种方法

App.js

import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import Err from './components/Err'
import Main from './components/Main'

class App extends Component {

  constructor(props){
    super(props)
    this.state = {
      err: null
    }
  this.setError = this.setError.bind(this)
  }

  setError(){
    return(
      this.setState(() => {
        return({
          err: 'Error'
        })
      })
    )
  }

  componentDidMount(){
    setTimeout(this.setError, 2000)
  }

  render() {
    return (
      <div className="App">
       { 
         this.state.err ? <Err /> : <Main />
       }
      </div>
    );
  }
}

export default App;
  

第二种方法

App.js

import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import Err from './components/Err'
import Main from './components/Main'

class App extends Component {

  constructor(props){
    super(props)
    this.state = {
      comp: <Main />
    }
  this.setError = this.setError.bind(this)
  }

  setError(){
    return(
      this.setState(() => {
        return({
          comp: <Err />
        })
      })
    )
  }

  componentDidMount(){
    setTimeout(this.setError, 2000)
  }

  render() {
    return (
      <div className="App">
       {this.state.comp}
      </div>
    );
  }
}

export default App;

2 个答案:

答案 0 :(得分:1)

两种方法基本相同,但我更喜欢选项1,因为它更容易掌握。您还可以使用类似babel-plugin-jsx-control-statements#choose的内容,使React组件看起来更简单:

<Choose>
  <When condition={ test1 }>
    <Main />
  </When>
  <When condition={ test2 }>
    <AnotherMain />
  </When>
  <Otherwise>
    <Err />
  </Otherwise>
</Choose>

答案 1 :(得分:1)

我绝对推荐第一种方法。存储数据(json),而不是组件状态中的视图(jsx)。

实际上有第三种方法可以充分利用两者:

  

在渲染之前使用jsx变量编辑视图(使用您的逻辑)

import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import Err from './components/Err';
import Main from './components/Main';

class App extends Component {

    constructor(props){
        super(props);
        this.state = {
            err: null
        };
    }

    // This way of writing functions saves you the binding
    setError = () => this.setState({err: 'Error'})

    componentDidMount(){
        setTimeout(this.setError, 2000);
    }

    render() {
        let comp = <Main />;
        // Put your logic here so your returned JSX is clear
        if (this.state.err)
            comp = <Err />;
        return (
            <div className="App">
              {comp}
            </div>
        );
    }
}

export default App;