【问题标题】:React Native wont render next array items at setStateReact Native 不会在 setState 处呈现下一个数组项
【发布时间】:2018-12-15 08:41:46
【问题描述】:

您好,我正在尝试制作一个步骤向导组件,但我遇到了以下问题。我有以下文件:

import React from 'react';
import { View } from 'react-native';
import WizardStep from './WizardStep'

export default class Wizard extends React.Component {

  constructor(props){
    super(props);
    this.state = {
      questions: this.props.questions,
      answers: this.props.answers,
      totalSteps: this.props.questions.length,
      currentStep: 0,
      results: []
    }
  }

  updateStep = answer =>  {
    newResults = this.state.results
    newResults[this.state.currentStep - 1] = answer
    this.setState({
      results: newResults,
      currentStep: this.state.currentStep + 1
    }, () => {
      if (this.state.currentStep == this.state.totalSteps) {
        this.props.finish();
      }
    })
  }

  renderStep = () => {
    if (this.state.currentStep < this.state.totalSteps) {
        return (
          <View>
            <WizardStep
              question={this.state.questions[this.state.currentStep]}
              answers={this.state.answers[this.state.currentStep]}
              step={this.state.currentStep}
              totalSteps={this.state.totalSteps}
              updateStep={this.updateStep}
            />
          </View>
        );
    } else {
        return null;
    }
  }

  render(){
      return(
          <View>
            {this.renderStep()}
          </View>
      )
  }
}

questions 是字符串数组,answers 是字符串数组数组。

无论如何,第一个屏幕显示得很好。但是当我调用updateStep 函数时,currentStep 会更新,但它不会显示问题/答案数组中的第二项。有任何想法吗?提前谢谢!

为向导添加其他组件:

import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
import { Button } from "react-native-elements";
import { Constants } from 'expo';
import WizardStepButton from './WizardStepButton';

export default class WizardStep extends React.Component {

  constructor(props){
    super(props);
    this.state ={ 
      question: this.props.question,
      answers: this.props.answers,
      totalSteps: this.props.totalSteps,
      step: this.props.step,
    }
  }
  renderAnswers = () => {
    var answers = []
    for (var i = 0; i < this.state.answers.length; i++) {
        answers.push(
          <WizardStepButton 
            answer={this.state.answers[i]}
            updateStep={this.props.updateStep}
            key={i}
          />
        );
    }
    return answers;
  }

  render(){
      return(
          <View>
            <Text style={styles.title}>Step {this.state.step + 1}/{this.state.totalSteps}</Text>
            <Text style={styles.title}>{this.state.question}</Text>
            {this.renderAnswers()}
          </View>
      )
  }
}

const styles = StyleSheet.create({
  title: {
    marginTop: 30,
    marginBottom: 30,
    fontSize: 25,
    color: 'rgba(96,100,109, 1)',
    lineHeight: 24,
    textAlign: 'center',
  },
});

和按钮组件:

import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
import { Button } from "react-native-elements";
import { Constants } from 'expo';

export default class WizardStepButton extends React.Component {

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

  render(){
      return(
          <View>
            <Button 
              style={{margin: 10}}
              large
              raised
              title={this.props.answer}
              onPress={() => this.props.updateStep(this.props.answer)}
            />
          </View>
      )
  }
}

【问题讨论】:

    标签: reactjs react-native expo


    【解决方案1】:

    您应该只使用状态更新器函数来增加状态值。 - https://stackoverflow.com/a/45196079/874027

    在编辑 this.state.results 并将其恢复为状态之前,您不会传播它们。

    currentStep 也会检查索引是否关闭。

    updateStep = answer =>  {
      this.setState((state) => {
        const { results, currentStep } = state
        const newResults = [...results]
        newResults[currentStep] = answer
        return {
          results: newResults,
          currentStep: currentStep + 1,
        }
      }, () => {
        const { currentStep, totalSteps } = this.state
        if (currentStep + 1 === totalSteps) {
          this.props.finish();
        }
      })
    }
    

    编辑:在 WizardStep 组件中,您将道具与构造函数中的状态同步,因此当您在更新状态后尝试传递新道具时,它们将永远不会反映在向导中,因为它的构造函数已经启动。您可以通过在 WizardStep 组件中使用道具来解决此问题,也可以通过向其传递一个键来解决此问题,这样每次键更改时都会创建新实例,例如

    <WizardStep
      question={this.state.questions[this.state.currentStep]}
      answers={this.state.answers[this.state.currentStep]}
      step={this.state.currentStep}
      totalSteps={this.state.totalSteps}
      updateStep={this.updateStep}
      key={this.state.currentStep}
    />
    

    我已经在本地对此进行了测试,并且使用这种方法确实改变了步骤。

    【讨论】:

    • 感谢您的回答。尝试了您的解决方案,但仍然无法呈现下一个问题。
    • 那么当您执行更新答案时究竟会发生什么?在 render 和 updateStep 方法周围放置一些控制台日志,看看 currentStep 和 results 使用了哪些值。
    • currentStep 更新并显示 1(这是正确的),结果也更新并在第一个字段中显示带有答案(字符串)的数组。但在我的屏幕上没有其他重要的事情。向导停留在第 1 步,仍然呈现第一个问题及其答案。
    • 如果有帮助的话,我也用其他组件的代码更新了我的问题。
    • 传递密钥解决了这个问题。非常感谢!
    猜你喜欢
    • 1970-01-01
    • 2020-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-23
    • 2019-07-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多