如何根据reactjs中的props动态定义this.state

时间:2017-11-13 06:57:03

标签: javascript reactjs

我的reactjs民意调查目前有这段代码:

//App.js
import React, { Component } from 'react';
import './App.css';

const PollOption = ({options,selected, onChange}) => {
   return (
    <div className="pollOption">
      {options.map((choice, index) => (
        <label key={index}>
        <input type="radio" 
                name="vote" 
                value={choice.value} 
                key={index}
                checked={selected === choice.value}
                onChange={onChange}/>
                {choice.text}
        </label>
      ))}  
    </div>
   );
};

const VoteCount = ({totalVotes, choiceOneVotes, choiceTwoVotes}) =>{
  return(
      <div className="VoteCount">
          <h2>Total Votes {totalVotes}</h2>
          <ul>
            <li>Yes: {choiceOneVotes}</li>
            <li>No: {choiceTwoVotes}</li>
          </ul>
      </div>
  );
}



class OpinionPoll extends Component{
  constructor(props) {
    super(props);
    this.state = {selectedOption: '', 
                  totalVotes: 0,
                  choiceOneVotes: 0,
                  choiceTwoVotes: 0}
  }

  handleClick(){
    console.log('submitted option', this.state.selectedOption);
    this.setState(prevState => {
      return {totalVotes: prevState.totalVotes + 1}
    })
   if(this.state.selectedOption === "yes"){
    this.setState(prevState => {
      return {choiceOneVotes: prevState.choiceOneVotes + 1}
    })
   }else{
    this.setState(prevState => {
      return {choiceTwoVotes: prevState.choiceTwoVotes + 1}
    })
   }
  }

  handleOnChange(e){
    console.log('selected option', e.target.name);
    this.setState({ selectedOption: e.target.value});
  }

  render(){
    return (
      <div className="poll">
        {this.props.model.question}
        <PollOption 
          options={this.props.model.choices}
          onChange={(e) => this.handleOnChange(e)}
          selected={this.state.selectedOption}/>

        <button onClick={() => this.handleClick()}>Vote!</button>
        <VoteCount 
          totalVotes={this.state.totalVotes}
          choiceOneVotes={this.state.choiceOneVotes}
          choiceTwoVotes={this.state.choiceTwoVotes}/>
      </div>
    );
  }
}


export default OpinionPoll;

//index.js
import React from 'react';
import {render} from 'react-dom';
import './index.css';
import OpinionPoll from './App';


var json = {
        question: 'Do you support cookies in cakes?',
        choices:
        [
           {text: "Yes", value: "yes"},
           {text: "No", value: "no"} 
        ]
    }
const root = document.getElementById("root");
render(<OpinionPoll model ={json} />, root)

我的handleClick()和VoteCount组件代码感觉不够优雅,因为如果我在轮询中添加选项数量,那么我必须去修改状态对象并添加另一个setState调用。我怎样才能让这种动态变化?

2 个答案:

答案 0 :(得分:0)

我想这就是你要找的东西。如果添加新选项,则将特定对象添加到选项中。

 handleClick(){
   const { selectedOption, choiceOneVotes, choiceTwoVotes, totalVotes  } = this.state
   const choices = {
     yes: { state: 'choiceOneVotes', value: choiceOneVotes },
     no : { state: 'choiceTwoVotes', value: choiceTwoVotes }
   }

   this.setState({
     totalVotes: totalVotes + 1,
     [choices[selectedOption]['state']]: choices[selectedOption]['value'] + 1
   });
 }

答案 1 :(得分:0)

const PollOption = ({options,selected, onChange}) => {
  return (
    <div className="pollOption">
      {options.map((choice, index) => (
        <label key={index}>
        <input type="radio" 
                name="vote" 
                key={index}
                onChange={(e)=>onChange(e,index)}/>
                {choice.tag}
        </label>
      ))}  
    </div>
   );
};

const VoteCount = ({totalVotes, options}) =>{
  return(
      <div className="VoteCount">
          <h2>Total Votes {totalVotes}</h2>
          <ul>
            {options.map((element,index)=>(
              <li>{element.tag}: {element.count}</li>
            ))}
          </ul>
      </div>
  );
}



class OpinionPoll extends React.Component{
  constructor(props) {
    super(props);
    this.state = {
      selectedOption: 0, 
      totalVotes: 0,
      choiceOneVotes: 0,
      choiceTwoVotes: 0,
      options: [
        {tag:"A", count:0},
        {tag:"B", count:0},
        {tag:"C", count:0},
        {tag:"D", count:0}
      ]
    }
  }

  handleClick(){
    this.setState(prevState => {
      return {totalVotes: prevState.totalVotes + 1}
    })
   const selectedIndex =   this.state.selectedOption
   const newOption = [...this.state.options]
   debugger
   newOption[selectedIndex].count += 1
    this.setState({
      options: newOption,
    })
  }

  handleOnChange(e,index){
    this.setState({
      selectedOption: index
    });
  }

  render(){
    return (
      <div className="poll">
        {this.props.model.question}
        <PollOption 
          options={this.state.options}
          onChange={(e,index) => this.handleOnChange(e,index)}
          selected={this.state.selectedOption}/>

        <button onClick={() => this.handleClick()}>Vote!</button>
        <VoteCount 
          totalVotes={this.state.totalVotes}
           options={this.state.options}
          />
      </div>
    );
  }
}



var json = {
        question: 'Do you support cookies in cakes?',
        choices:
        [
           {text: "Yes", value: "yes"},
           {text: "No", value: "no"} 
        ]
    }
const root = document.getElementById("root");
ReactDOM.render(<OpinionPoll model ={json} />, root)
//ReactDOM.render(<div>test </div>, root)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>

这样可以添加动态选择