リアクトに多くの子要素のいずれかを選択するための正しい方法は何ですか?

JoeMajor:

私は、テキストのブロックが含まれている私の新しいリアクトアプリのごく一部いるAllLines、ライン・バイ・ラインのコンポーネントに分割と呼ばれますLine私はそれが1行をクリックしたときに、それを選択して、編集可能な他のすべての行がとして表示されますされるように動作するようにしたい<p>要素。どのように私は最高のラインの一方のみが任意の時点で選択されていることを、ここで状態を管理するようにできますか?私は苦労しています一部が決定されたLine親がその状態を変えることができるような方法でクリックされた要素。

私はこのような状況ではベストプラクティスであるかを調べることに熱心だきちんと物事を行うことにより、「リアクトで思考」私は、私は、この作品を作ることができるという方法を知っているが、私は反応するように、比較的新しいですし、に私の頭を取得しようとしています。

class AllLines extends Component {
    state = {
        selectedLine: 0,
        lines: []
    };

    handleClick = (e) => {
        console.log("click");
    };

    render() {
        return (
            <Container>
                {
                    this.state.lines.map((subtitle, index) => {
                        if (index === this.state.selectedLine) {
                            return (
                                <div id={"text-line-" + index}>
                                    <TranscriptionLine
                                        lineContent={subtitle.text}
                                        selected={true}
                                    />
                                </div>
                            )
                        }
                        return (
                            <div id={"text-line-" + index}>
                                <Line
                                    lineContent={subtitle.text}
                                    handleClick={this.handleClick}
                                />
                            </div>
                        )
                    })
                }
            </Container>
        );
    }
}
class Line extends Component {

    render() {
        if (this.props.selected === true) {
            return (
                <input type="text" value={this.props.lineContent} />
            )
        }
        return (
            <p id={} onClick={this.props.handleClick}>{this.props.lineContent}</p>
        );
    }
}
Yevgen Gorbunkov:

「内の思考が反応」あなたが彼らのユニークでグラブDOM要素へのあなたの習慣を放棄したいと思いますid;)

私が見たものから、あなたのコードベースから欠落しているが、いくつかの部品:

  • 一度に選択された唯一のラインを維持するスマートクリックハンドラ
  • 親状態内の行の内容を変更しますコールバックに固執する編集行ハンドラ
  • 編集ライン可能な行のための、好ましくは2つの別個の構成要素は、実際には別の方法でそれらの挙動として編集し、異なるDOM要素として表示されています

上記をラップするために、私は少し思い言い換える以下にコードを:

const { Component } = React,
      { render } = ReactDOM
      
const linesData = Array.from(
        {length:10},
        (_,i) => `There goes the line number ${i}`
      )      
      
class Line extends Component {
  render(){
    return (
      <p onClick={this.props.onSelect}>{this.props.lineContent}</p>
    )
  }
}

class TranscriptionLine extends Component {
  constructor(props){
    super(props)
    this.state = {
      content: this.props.lineContent
    }
    this.onEdit = this.onEdit.bind(this)
  }
  
  onEdit(value){
    this.setState({content:value})
    this.props.pushEditUp(value, this.props.lineIndex)
  }
  
  render(){
    return (
      <input
        style={{width:200}}
        value={this.state.content} 
        onChange={({target:{value}}) => this.onEdit(value)} 
      />
    )
  }
}

class AllLines extends Component {
    constructor (props) {
      super(props)
      this.state = {
        selectedLine: null,
        lines: this.props.lines
      }
      this.handleSelect = this.handleSelect.bind(this)
      this.handleEdit = this.handleEdit.bind(this)
    }
    
    handleSelect(idx){
      this.setState({selectedLine:idx})
    }
    
    handleEdit(newLineValue, lineIdx){
      const linesShallowCopy = [...this.state.lines]
      linesShallowCopy.splice(lineIdx,1,newLineValue)
      this.setState({
        lines: linesShallowCopy
      })
    }

    render() {
        return (
            <div>
                {
                    this.state.lines.map((text, index) => {
                        if(index === this.state.selectedLine) {
                            return (
                                    <TranscriptionLine
                                        lineContent={text}
                                        lineIndex={index}
                                        pushEditUp={this.handleEdit}
                                    />
                            )
                        }
                        else
                            return (
                                    <Line
                                        lineContent={text}
                                        lineIndex={index}
                                        onSelect={() => this.handleSelect(index)}
                                    />
                            )
                    })
                }
            </div>
        )
    }
}

render (
  <AllLines lines={linesData} />,
  document.getElementById('root')
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.12.0/umd/react.production.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.11.0/umd/react-dom.production.min.js"></script><div id="root"></div>

おすすめ

転載: http://10.200.1.11:23101/article/api/json?id=7861&siteId=1