【问题标题】:ReactJS selecting an element uniquely from a mapReactJS 从地图中唯一地选择一个元素
【发布时间】:2019-05-31 21:14:59
【问题描述】:

我正在做一个 todo 应用来练习 React。我击中了一个拦截器,现在我正试图弄清楚如何唯一地编辑一张卡片。

目前当我点击编辑时,我所有的卡片都设置为isEditing == true。我尝试添加键和索引,但似乎无法唯一标识所选卡。

如我的 gif 图中所示:

显然预期的结果是它应该只将isEditing == true 设置为选定的卡。

请参阅下面的代码。

更多上下文: 有状态组件将道具传递给该组件,我使用react-bootstrap(因此PanelButton),我删除了一些简洁的代码(construct 等等)。

    edit() {
        this.setState({
            isEditing: true
        })
    }

    renderEditDoneButtons() {
        return (
            <div>
                <Button onClick={this.edit}>edit</Button>
            </div>
        )
    }

    renderNote(note) {
        return (
            <p> {note} </p>
        )
    }

    renderCard(note, i) {
        return (
            <Panel key={i}
                   index={i}>
                {
                    this.state.isEditing ? 
                    this.renderForm() : 
                    this.renderNote(note.note)
                }
            </Panel>
        )
    }

    render() {
        return (
            <div>
                {this.props.notes.map(this.renderCard)}
            </div>
        )
    }  

【问题讨论】:

  • 同一个id的renderEditDoneButtons()按钮怎么链接到卡片上?如果按钮与卡片具有相同的 ID,您可以创建一个数组,其中每个卡片都有单独的编辑状态。或者您可以有一个变量来存储当前正在编辑的卡片的 ID,然后您可以相应地显示该卡片
  • 您希望一次只能编辑一个吗?或者你想让用户基本上打开/关闭编辑?

标签: javascript reactjs ecmascript-6 frontend


【解决方案1】:

这三个都根据您的单个isEditing 状态而变化,这就是为什么当您单击任何“编辑”按钮时会显示所有三个。代替单个isEditing 状态键,使用数组来维护所有三种状态,如下所示:

constructor(props) {

  super(props);

  // Sets a true/false editing state for all three panels
  this.state = {
    editingPanels: Array(3).fill(false)
  }
}

edit(i) {

    // Switches editing state to false/true for given i
    const editingPanels = this.state.editingPanels.slice();
    editingPanels[i] = !editingPanels[i];

    this.setState({
        editingPanels: editingPanels
    })
}

renderEditDoneButtons(i) {
    return (
        <div>
            <Button onClick={()=>this.state.edit(i)}>edit</Button>
        </div>
    )
}

renderNote(note) {
    return (
        <p> {note} </p>
    )
}

renderCard(note, i) {
    return (
        <Panel key={i}
               index={i}>
            {
                this.state.editingPanels[i] ? 
                this.renderForm() : 
                this.renderNote(note.note)
            }
        </Panel>
    )
}

render() {
    return (
        <div>
            {this.props.notes.map(this.renderCard)}
        </div>
    )
} 

【讨论】:

  • const editingPanels = this.state.editingPanels.slice(); 可以重构为const editingPanels = this.state.editingPanels
  • @e_mam106 正确 - 如果你想跟踪用户输入的历史,Facebook 建议使用 slice,所以我这样做是出于习惯 :)
【解决方案2】:

您可以为每个待办事项列表项使用一个单独的组件,并在 map 方法中使用它。以下示例给出了如何实现这一点的想法。我正在使用另一个示例,因为您没有提供完整的代码。

class EditText extends React.Component {
  constructor(props) {
    super(props)
    this.state = {value:props.data,newValue:'hi'}
    this.editValue = this.editValue.bind(this)
  }
  editValue() {
    this.setState({value:this.state.newValue})
  }
  render() {
    return(
      <div>
      {this.state.value}
      <button onClick={this.editValue}>Change text to Hi</button>
      </div>
    )
  }
}
class App extends React.Component {
  constructor() {
    super()
    this.state = {tempDate : ['hello','how']}
  }
  render() {
    return (
      <div className="App">
      {this.state.tempDate.map(data=>(<EditText data={data}/>))}
      </div>
    );
  }
}

【讨论】:

    【解决方案3】:

    您需要为每张特定卡设置状态变量 isEditing。 如果有 3 张卡,则需要有 3 个变量。

    编辑 1:- 示例已由 Kody R 共享。

    我注意到的一件事是,我们可以通过 props 中收到的音符数量来分配数组大小,而不是将数组大小硬编码为 3。

    this.state = {
        editingPanels: Array(3).fill(false)
      }
    

    this.state = {
        editingPanels: Array(this.props.notes.length).fill(false)
      }
    

    希望这有帮助,

    干杯!!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-10-17
      • 1970-01-01
      • 2020-02-26
      • 2021-04-19
      • 1970-01-01
      • 1970-01-01
      • 2010-09-08
      • 1970-01-01
      相关资源
      最近更新 更多