简体   繁体   English

单选按钮的反应矩阵

[英]React Matrix of Radio buttons

I tried to solve this js react problem and get stuck on questions 2-4.我试图解决这个 js react 问题并被困在问题 2-4 上。 Question 2: I don't know how to check the local state for each row in order check for the duplicate rank select Question 3: Should I need props passed to the component to check for unique?问题 2:我不知道如何检查每一行的本地状态以检查重复的等级选择问题 3:我是否需要将道具传递给组件来检查唯一性? Question 4: How do I check all rows have a select ranked and unique?问题 4:如何检查所有行都具有选择排名和唯一性?

Here are the questions:以下是问题:

  1. Adding a class of "done" to a row will highlight it green.将“完成”类添加到行中会将其突出显示为绿色。 Provide this visual feedback on rows which have a selected rank.对具有选定等级的行提供此视觉反馈。

  2. Adding a class of "error" to a row will highlight it red.将“错误”类添加到行中会将其突出显示为红色。 Provide this visual feedback on rows which have duplicate ranks selected.在选择了重复排名的行上提供此视觉反馈。

  3. There is a place to display an error message near the submit button.在提交按钮附近有一个显示错误消息的地方。 Show this error message: Ranks must be unique whenever the user has selected the same rank on multiple rows.显示此错误消息:当用户在多行上选择相同的排名时, Ranks must be unique的。

  4. The submit button is disabled by default.默认情况下禁用提交按钮。 Enable it when all rows have a rank selected and all selected ranks are unique.当所有行都选择了一个等级并且所有选定的等级都是唯一的时启用它。

The orginal App.js原始 App.js

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

class App extends Component {
  render() {
    return (
      <MainPage />
    );
  }
}

export default App;

MainPage.js主页.js

import React from 'react';
import _ from 'lodash';
import FormRow from './FormRow.jsx';
import Animal from './Animal.js';

class MainPage extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      animals: ['panda','cat','capybara','iguana','muskrat'].map((name) => {
        return new Animal(name);
      }),
      error: ''
    };
  }


  render() {
    const rows = this.state.animals.map((animal) => {
      return (
        <FormRow
          animalName={animal.name}
          key={animal.name}
        />
      );
    });

    const headers = _.range(1, 6).map((i) => <th key={`header-${i}`}>{i}</th>);

    return (
      <div>
        <table>
          <thead>
            <tr>
              <th></th>
              {headers}
            </tr>
          </thead>
          <tbody>
            {rows}
          </tbody>
        </table>
        <div>{this.state.error}</div>
        <input type="submit" />
      </div>
    );
  }
}

export default MainPage;

FormRow.jsx表格行.jsx

import React from 'react';
import _ from 'lodash';

class FormRow extends React.Component {
  render() {
    const cells = _.range(1, 6).map((i) => {
      return (
        <td key={`${this.props.animalName}-${i}`}>
          <input
            type="radio"
            name={this.props.animalName}
            value={i}
          />
        </td>
      );
    });

    return (
      <tr>
        <th>{this.props.animalName}</th>
        {cells}
      </tr>
    )
  }
}

export default FormRow;

Animal.js动物.js

class Animal {
  constructor(name, rank) {
    this.name = name;
    this.rank = rank;
  }
}

export default Animal;

My code is at GitHub (git@github.com:HuydDo/js_react_problem-.git).我的代码在 GitHub (git@github.com:HuydDo/js_react_problem-.git)。 Thanks for your suggestion!谢谢你的建议!

FormRow.jsx表格行.jsx

import React from 'react';
import _ from 'lodash';

class FormRow extends React.Component {

  constructor(){
    super();
    this.state = {
      rowColor : false,
      name: "",
      rank: 0
        // panda: 0,
        // cat:  0,
        // capybara: 0,
        // iguana:  0,
        // muskrat:  0
    }
  }

  handleChange = (e) => {
    if (this.state.rank === e.target.value){
      console.log("can't select same rank.")
    }
    console.log(e.target.name)
    console.log(e.target.value)
    this.setState({
      // [e.target.name]: e.target.value,
      name: e.target.name,
      rank: e.target.value,
      rowColor: true
    }, console.log(this.state))
  }
  
  handleChange2 = (e) => {
    let newName = e.target.name
    let newRank = e.target.value
    let cRank = this.state.rank
    let cName = this.state.name
    console.log(this.state)
    console.log(`${newRank} ${newName}`)

    if(cName !== newName) {
      if(cRank !== newRank) {
        this.setState({
         name : newName,
         rank: newRank,
         rowColor: true
        },()=> console.log(this.state))
      }
      else {
        console.log("can't select same rank")
      }
    }

    //  this.setState(previousState => {
       
    //    let cRank = previousState.rank
    //    let cName = previousState.name
    //    console.log(previousState) 

    //    return {
    //       rank: newRank,
    //       name: newName,
    //       rowColor: true
    //      }
    //  },console.log(this.state.rank))
  }

  render() {
    const cells = _.range(1, 6).map((i) => {
      return (
        <td key={`${this.props.animalName}-${i}`} onChange={this.handleChange2}>
          <input 
            type="radio"
            name={this.props.animalName}
            value={i}
          /> 
        </td>
      );
    });

    return (
     
      <tr className = {(this.state.rowColor) ? 'done':null}  >
      {/* <tr> */}
        <th>{this.props.animalName}</th>
        {cells}
      </tr>
    )
  }
}

export default FormRow;

MainPage.jsx主页.jsx

import React from 'react';
import _ from 'lodash';
import FormRow from './FormRow.jsx';
import Animal from './Animal.js';

class MainPage extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      animals: ['panda','cat','capybara','iguana','muskrat'].map((name) => {
        return new Animal(name);
      }),
      error: ''
    };
  }

  getValue = ({name,rank}) =>{
      console.log(`Name: ${name} rank: ${rank}`)
  }
  
  // handleSubmit = event => {
   
  //   event.preventDefault()
  //   this.props.getValue(this.state)
  // }

  checkForUnique = () => {
    // Show this error message: `Ranks must be unique` whenever the user has selected the
  //  same rank on multiple rows.
    this.setState({
      error : "Ranks must be unique"
    })  
  
  }

  isDisabled = () =>{
   // The submit button is disabled by default. Enable it when all rows have a
   // rank selected and all selected ranks are unique.
    return true
  }

  render() {

    const rows = this.state.animals.map((animal) => {
      return (
        <FormRow
          animalName={animal.name}
          key={animal.name}
          rank={animal.rank}
          handleChange={this.handleChange}
          getValue={this.getValue}
        />
      );
    });

    const headers = _.range(1, 6).map((i) => <th key={`header-${i}`}>{i}</th>);

    return (
      <div>
        {/* <form onSubmit={this.onSubmit}> */}
        <table>
          <thead>
            <tr>
              <th></th>
              {headers}
            </tr>
          </thead>
          <tbody>
            {rows}
          </tbody>
        </table>
        <div>{this.state.error}</div>
        <input type="submit" value="Submit" disabled={this.isDisabled()} />        {/* <button type="submit">Submit</button> */}
        {/* </form> */}
      </div>
    );
  }
}

export default MainPage;

enter image description here在此处输入图片说明

I tried to add handleChange and handleAnimalSelect methods, but I get an error.我尝试添加 handleChange 和 handleAnimalSelect 方法,但出现错误。 The new name and rank are not added to the arrays.新名称和等级不会添加到数组中。

在此处输入图片说明

MainPage.jsx主页.jsx

import React from 'react';
import _ from 'lodash';
import FormRow from './FormRow.jsx';
import Animal from './Animal.js';

class MainPage extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      animals: ['panda','cat','capybara','iguana','muskrat'].map((name) => {
        return new Animal(name);
      }),
      error: ''
    };
  }


  isDisabled = () =>{
   // The submit button is disabled by default. Enable it when all rows have a
   // rank selected and all selected ranks are unique.
    return true
  }

  render() {

    const rows = this.state.animals.map((animal) => {
      return (
        <FormRow
          animalName={animal.name}
          key={animal.name}
          rank={animal.rank}
         
          getValue={this.getValue}
          handleAnimalSelect={this.handleAnimalSelect}
        />
      );
    });

    const headers = _.range(1, 6).map((i) => <th key={`header-${i}`}>{i}</th>);

    return (
      <div>
        {/* <form onSubmit={this.onSubmit}> */}
        <table>
          <thead>
            <tr>
              <th></th>
              {headers}
            </tr>
          </thead>
          <tbody>
            {rows}
          </tbody>
        </table>
        <div>{this.state.error}</div>
        <input type="submit" value="Submit" disabled={this.isDisabled()} />        
        {/* <button type="submit">Submit</button> */}
        {/* </form> */}
      </div>
    );
  }
}

export default MainPage;

FormRow.jsx表格行.jsx

import React from 'react';
import _ from 'lodash';
import FormRow from './FormRow.jsx';
import Animal from './Animal.js';

class MainPage extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      animals: ['panda','cat','capybara','iguana','muskrat'].map((name) => {
        return new Animal(name);
      }),
      error: ''
    };
  }


  isDisabled = () =>{
   // The submit button is disabled by default. Enable it when all rows have a
   // rank selected and all selected ranks are unique.
    return true
  }

  render() {

    const rows = this.state.animals.map((animal) => {
      return (
        <FormRow
          animalName={animal.name}
          key={animal.name}
          rank={animal.rank}
         
          getValue={this.getValue}
          handleAnimalSelect={this.handleAnimalSelect}
        />
      );
    });

    const headers = _.range(1, 6).map((i) => <th key={`header-${i}`}>{i}</th>);

    return (
      <div>
        {/* <form onSubmit={this.onSubmit}> */}
        <table>
          <thead>
            <tr>
              <th></th>
              {headers}
            </tr>
          </thead>
          <tbody>
            {rows}
          </tbody>
        </table>
        <div>{this.state.error}</div>
        <input type="submit" value="Submit" disabled={this.isDisabled()} />        
        {/* <button type="submit">Submit</button> */}
        {/* </form> */}
      </div>
    );
  }
}

export default MainPage;

You're pretty much making a form with a few rows of multiple choice answers.您几乎正在制作一个包含几行多项选择答案的表格。

One way of simplifying everything is to have all the logic in the top component, in your case I think MainPage would be where it would be.简化所有内容的一种方法是将所有逻辑放在顶部组件中,在您的情况下,我认为MainPage将是它所在的位置。 Pass down a function as a prop to all the descendants that allows them to update the form data upstream.将函数作为道具传递给所有后代,允许他们更新上游表单数据。

In Q2, how do intend to check the state for each row?在 Q2 中,打算如何检查每一行的状态? Perhaps you can use arrays or objects to keep track of the status of each question.也许您可以使用数组或对象来跟踪每个问题的状态。 The arrays/objects are stored in state, and you just check them to see what the status is.数组/对象存储在状态中,您只需检查它们以查看状态。

I'm actually not clear what your app looks like - what does a row look like?我实际上不清楚您的应用程序是什么样的 - 一行是什么样的? (You might want to post a screenshot) And I don't see any way for rank to be selected - I don't even see what the ranks are for, or how they are used in the form. (您可能想要张贴屏幕截图)而且我没有看到任何选择排名的方法 - 我什至不知道排名的用途,或者它们在表格中的使用方式。 So perhaps your form design needs to be tweaked.所以也许你的表单设计需要调整。 You should begin the form design with a clear picture in YOUR mind about how the app will work.您应该从脑海中清楚地了解应用程序的工作原理来开始表单设计。 Maybe start by drawing the screens on paper and drawing little boxes that will represent the objects/array variables and go through the process of a user using your app.也许首先在纸上绘制屏幕并绘制代表对象/数组变量的小框,然后完成用户使用您的应用程序的过程。 What happens to the various boxes when they click radio buttons and so on.单击单选按钮等时,各种框会发生什么。 How will you know if the same rank is selected twice - where are the selected ranks stored?您如何知道是否选择了两次相同的排名 - 所选排名存储在哪里? What animals are clicked/selected?点击/选择了哪些动物? Where are those stored?那些存储在哪里? Draw it all on paper first.先全部画在纸上。

Array or objects: If you want to keep it simple, you can do the whole project just using arrays.数组或对象:如果你想保持简单,你可以只使用数组来完成整个项目。 You can have one array that stores all the animals.您可以拥有一个存储所有动物的数组。 You can have a different array that stores which animals are selected right NOW (use .includes() to test if an animal is in that array).您可以有一个不同的数组来存储现在选择的动物(使用 .includes() 测试动物是否在该数组中)。 You can have another array that stores the rows that have a rank selected.您可以使用另一个数组来存储已选择排名的行。 When the number of elements in that row === the number of rows (is that the same as the number of animals? If yes, then you can use the length of the animals array for that test)当该行中的元素数 === 行数时(是否与动物数相同?如果是,那么您可以使用动物数组的长度进行该测试)

How do you know if the rows with a rank selected are unique?您如何知道所选排名的行是否唯一? One way is to DISALLOW selected a rank that has already been selected.一种方法是 DISALLOW 选择一个已经被选择的等级。 Again, use .includes() (eg arrSelectedRanks.includes(num) ) to check if a rank has already been selected.同样,使用 .includes() (例如arrSelectedRanks.includes(num) )来检查是否已经选择了排名。

SO what do one of these checks look like?那么这些检查之一是什么样的?

const handleAnimalSelect = (animal) => {
   const err = this.state.selectedAnimals.includes(animal);
   if (err === true){
       this.setState(error: animal);
   }
}

return (
  <input
     type="radio"
     name={this.props.animalName}
     value={i}
     onClick={this.handleAnimalSelect}
  />

  { error !== undefined && (
    <div class={style.errorMessage}>{`Animal ${} was chosen twice`}</div>
  )}

);


};

Remember: State is what you use for remembering the value of variables in a given component.记住:状态是你用来记住给定组件中变量值的东西。 Every component has its own state.每个组件都有自己的状态。 But Props are for data/functions/elements that are passed into the component.但是 Props 用于传递到组件中的数据/函数/元素。 You don't update the values of props in the component (prop values are stored in another component. If you need to update them, you use functions to pass data back to the parent component where that variable is in state, and update the value there).您不会更新组件中 props 的值(prop 值存储在另一个组件中。如果您需要更新它们,您可以使用函数将数据传回该变量处于状态的父组件,并更新该值那里)。

Here is an example that uses .includes() to check for the presence/absence of something:这是一个使用.includes()检查某物的存在/不存在的示例:

https://stackoverflow.com/a/64486351/1447509 https://stackoverflow.com/a/64486351/1447509

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM