【问题标题】:Rendering multiple items with different props React ES6使用不同的道具渲染多个项目 React ES6
【发布时间】:2017-12-05 08:51:12
【问题描述】:

编辑---------- -------------->

我希望有一种方法,我只需要一个 onChange 函数,但似乎没有提供的任何答案。然而,我错了。感谢Kind user's answer,我能够理解这是可能的(尽管不是立即,正如您从 cmets 中得知的那样)。因此,我创建了自己的版本,我已经对其进行了测试并且正在运行。

我们有课程CheckboxesField.js

import React from 'react'
import Checkbox from 'material-ui/Checkbox'
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider'

const CheckboxesField = props => {
  const checkboxes = props.allPossibleCheckboxes.map(checkbox =>
    <Checkbox style={{ width: '20%' }}
      checked={props.checked.includes(checkbox)}
      onCheck={props.onCheck}
      key={checkbox}
      label={checkbox}
      id={checkbox}
      iconStyle={{ fill: '#000' }} />)
    return (
      <MuiThemeProvider>
        <div style={{ display: 'flex' }}>
          {checkboxes}
        </div>
      </MuiThemeProvider>
    )
  }

export default CheckboxesField

和班级index.js

import React, { Component } from 'react'
import ReactDOM from 'react-dom'
import CheckboxesField from './CheckboxesField'

class Index extends Component {
  constructor() {
    super()
    this.state = {
      checked: ["two", "five"],
      allPossible: ["one", "two", "three", "four", "five"],
    }
    this.onCheck = this.onCheck.bind(this)
  }

  onCheck(e, v) {
    const checked = this.state.checked
    if (v) {
      checked.push(e.target.id)
    } else {
      checked.splice(checked.indexOf(e.target.id), 1)
    }
    this.setState({ checked })
  }

  render() {
    return (
      <div className="index">
        <CheckboxesField
          allPossibleCheckboxes={this.state.allPossible}
          checked={this.state.checked}
          onCheck={this.onCheck}/>
      </div>
    )
  }
}

export default Index
ReactDOM.render(<Index />, document.getElementById('root'))

通过操作 2 个数组,一个包含所有可能的复选框,一个包含选定值,我们可以使用单个 onCheck 函数,我们不需要每个复选框的状态。

我想要这个的原因是,我想从数据库中获取选中的字段,通过这种方式,可以简单地向数据库添加另一个复选框,并且不需要更改代码,它就可以工作。


原始问题

我正在尝试创建一个材质 ui 复选框的字段。

我知道我能做到

<div style={{ display: 'flex' }}>
      <Checkbox style={{ width: '20%' }} checked={{ props.checkedOne }} onCheck={{ props.onCheckOne }} key={"one"} label={"one"} iconStyle={{ fill: '#000' }} />
      <Checkbox style={{ width: '20%' }} checked={{ props.checkedTwo }} onCheck={{ props.onCheckTwo }} key={"two"} label={"two"} iconStyle={{ fill: '#000' }} />
      .
      .
      .
</div>

无论我需要多少复选框。然而,这变得烦人并且涉及大量写作。

因此,我有一个 CheckboxesFields 类,它基于名为 labelsList 的道具映射复选框,其中包含 String 类型的列表

import React from 'react'
import Checkbox from 'material-ui/Checkbox'
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider'

const CheckboxesField = props => {
  const checkboxes = props.labelsList.map(label => <Checkbox style={{ width: '20%' }} key={label} label={label} iconStyle={{ fill: '#000' }} />)
    return (
      <MuiThemeProvider>
        <div style={{ display: 'flex' }}>
          {checkboxes}
        </div>
      </MuiThemeProvider>
    )
  }

export default CheckboxesField

然后在 App.js 中调用它

import React, { Component } from 'react'
import ReactDOM from 'react-dom'
import CheckboxesField from './CheckboxesField'

class App extends Component {
  render() {
    return (
      <div className="App">
        <CheckboxesField labelsList={["1", "2", "3", "4", "5"]} />
      </div>
    )
  }
}

export default App
ReactDOM.render(<App />, document.getElementById('root'))

这可行,但与第一个示例不同,如果我通过道具 onCheckchecked 它将适用于每个复选框。但是我希望每个复选框都可以单独控制。

我该怎么做呢?

感谢您的帮助。

【问题讨论】:

  • 传递对象中的数据,如labelsList={[{key: 1,checked: checkedOne}.....]}
  • 谢谢苗条!像魅力一样工作:)

标签: javascript reactjs checkbox ecmascript-6 material-ui


【解决方案1】:

不仅将标签传递给道具,还传递回调函数

import React, { Component } from 'react'
import ReactDOM from 'react-dom'
import CheckboxesField from './CheckboxesField'

let myfunc1 = () => { console.log("Hello World!") };

let labelsList = [
    {
       onCheck: myfunc1,
       checked: true,
       label: '1',
    },...
];    

class App extends Component {
  render() {
    return (
      <div className="App">
        <CheckboxesField labels={labelsList} />
      </div>
    )
  }
}

export default App
ReactDOM.render(<App />, document.getElementById('root'))

稍后在复选框生成器中像这样调用传递的回调。

import React from 'react'
import Checkbox from 'material-ui/Checkbox'
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider'

const CheckboxesField = props => {
  const checkboxes = props.labelsList.map(label => <Checkbox 
                             style={{ 
                                   width: '20%' 
                              }} 
                              key={label.label} 
                              label={label.label}
                              onCheck={label.onCheck}
                              checked={label.checked}
                              iconStyle={{ fill: '#000' }} 
   />);
    return (
      <MuiThemeProvider>
        <div style={{ display: 'flex' }}>
          {checkboxes}
        </div>
      </MuiThemeProvider>
    )
  }

export default CheckboxesField

【讨论】:

    【解决方案2】:

    建议的方法:

    app.js

    class App extends Component {
    
      handleCheckbox(event, isChecked, id) {
        console.log(isChecked, id); // will determine which checkbox was changed
                                    // and what is it's actual state (checked or not)
      }
    
      labelList = [1,2,3,4,5]; // rather temporary solution
    
      render() {
        return (
          <div className="App">
            {this.labelList.map(element => (
              <CheckboxesField 
                key={element} 
                label={element} 
                onChange={this.handleCheckbox} 
              />
            )}
          </div>
        )
      }
    }
    

    Checkbox component

    export class CheckboxesField extends React.PureComponent {
    
      handleCheck = (event, isInputChecked) => {
        this.props.onChange(event, isInputChecked, this.props.label);
      };
    
      render() {
        return (
              <Checkbox
                style={{width: '20%'}}
                label={this.props.label}
                iconStyle={{fill: '#000'}}
                onCheck={this.handleCheck}
              />
        )}
    }
    

    【讨论】:

    • 我不确定如何使用它。我需要能够清楚地识别哪些复选框已被选中并将该数据发送到数据库。我还需要根据挂载数据库中的数据检查一些框。我不确定如何使用这段代码做到这一点。
    • @Cornelius handleCheckbox 函数返回实际选中复选框的 idisChecked 布尔值(无论是否选中)。它对你来说可能看起来有点复杂,但只需花一些时间彻底检查一下,这是 imo 最好的解决方案。其他解决方案是硬编码或 jQuery-likeMaterial-UI 有自己的内置函数来处理检查事件,不需要自己编写函数来处理它。
    • 我明白了,但是当组件安装时,我将如何查找应该检查哪些复选框,因为我需要调用 onCheck 来获取状态和 ID,因为它们实际上并没有存储作为国家。
    • @Cornelius 但是存储数据有什么意义呢?您需要在安装组件之前自动检查其中的一些吗?
    • @Cornelius 事情是这样的。如果要指定是否必须选中某些复选框,则需要使用对象数组。 Material-UI 复选框接受它作为 checked 属性。如果您花几分钟时间仔细阅读 UI 复选框的文档,您就会知道所需的一切。
    【解决方案3】:

    正如其他人所建议的,您不仅要提供标签列表,还要检查每个复选框的状态和适当的 onCLick 功能,例如:

    const cbData = [ {label: "hm", checked: .. , onClick:..}, {label: "hm", checked: .. , onClick} ... ]
    

    标签和检查没有问题,onClick 涉及更多,因为您实际上需要为每个复选框提供不同的功能。这可以通过柯里化或某种函数生成器函数来完成,如果你愿意的话。喜欢在:

    const onClickGenerator = (checkboxId) => () => console.log("clicked cbox " + checkboxId)
    

    如果你调用onClickGenerator("myId"),你会得到一个不带参数的函数,当调用这个函数时会显示clicked cbox myId

    有了它,我们可以从 cbData 生成复选框组件数组(内部不需要 onClick):

    cbData.map((label) => (<Checkbox 
                                 style={{ 
                                       width: '20%' 
                                  }} 
                                  key={label.label} 
                                  label={label.label}
                                  onCheck={onClickGenerator(label.label)}
                                  {...(label.checked ? ({checked:true}) : ({}))}
                                  iconStyle={{ fill: '#000' }}
    

    【讨论】:

      猜你喜欢
      • 2022-01-02
      • 2021-03-21
      • 1970-01-01
      • 2019-07-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-26
      相关资源
      最近更新 更多