反应-映射数组未将道具正确传递给子组件

时间:2019-10-07 21:31:15

标签: javascript arrays reactjs

我正在制作一个仪表板组件,该组件显示渲染的预览和HTML代码段的代码。在仪表板组件内部,我正在使用cycleNext :: (Eq a, Enum a, Bounded a) => a -> a cycleNext maxBound = minBound cycleNext = succ 映射代码片段数组。每个映射的代码段都将具有删除功能(已构建)和更新功能。

为使更新功能正常工作,每个代码片段都有自己的子模式组件。我需要将代码段的ID传递给模式组件,在该组件中我可以将ID与新内容结合起来,然后再更新数据库和状态。

但是,当我将ID作为道具传递给模式时,我在某个地方犯了错误。

#include <stdio.h> #include <stdlib.h> #define SIZE 10 int main(void) { int a[SIZE] = {2, 6, 4, 8, 10, 12, 89, 68, 45, 37}; int noc = 0; puts("Data items in original order"); for (int noc = 0; noc < 9; noc++) { printf("\n"); for (size_t i = 0; i + noc < SIZE; i++) { printf("%4d", a[i]); } for (int pass = 1; pass < SIZE; pass++) { for (size_t i = 0; i < SIZE - pass; i++) { if (a[i] > a[i - 1]) { int hold = a[i]; a[i] = a[i - 1]; a[i - 1] = hold; } } } } for (int pass = 1; pass < SIZE; pass++) { for (size_t i = 0; i < SIZE - pass; i++) { if (a[i] > a[i + 1]) { int hold = a[i]; a[i] = a[i + 1]; a[i + 1] = hold; } } } puts("\nData items in ascending order"); for (size_t i = 0; i + noc < SIZE; i++) { printf("%4d", a[i]); } puts(""); } 在我的Dashboard.js Dashboard类组件中使用。

.map

这将在下面呈现片段(3个片段窗格,包括其数据库ID)。

enter image description here
打开按钮将打开下面的模式(Modal.js)。

.map

位于渲染下方的{this.state.snippets.map(snippet => ( <> <div key={snippet._id} className="holder--pod"> <div className="content"> <div className="content__snippet-preview"> Snippet preview </div> <div className="content__body"> <h4>{snippet.name}</h4> <p>{snippet.details}</p> <p>{snippet._id}</p> //THIS WORKS <pre> <code>{snippet.content}</code> </pre> </div> <div className="content__button"> <button onClick={this.handleDelete(snippet._id)}> Delete </button> <button type="button" onClick={this.showModal}> Open </button> </div> </div> </div> <Modal sid={snippet._id} //PASS ID HERE show={this.state.show} handleClose={this.hideModal} ></Modal> </> ))} 实际上会粘贴正确的3 ID控制台。 enter image description here

但是,无论我打开哪个Modal,在Modal.js返回中调用ID(import React, { Component } from 'react' import api from '../api' export default class Modal extends Component { constructor(props) { super(props) this.state = { name: '', details: '', content: '', message: null, } } handleInputChange = event => { this.setState({ [event.target.name]: event.target.value, }) } handleClick = id => event => { event.preventDefault() console.log(id) } render() { const { sid, show, handleClose } = this.props console.log(sid) const showHideClassName = show ? 'modal display-flex' : 'modal display-none' return ( <div id="Modal" className={showHideClassName}> <div id="modal-main"> <h4>Edit snippet {sid}</h4> <form> Name:{' '} <input type="text" value={this.state.name} name="name" onChange={this.handleInputChange} />{' '} <br /> Details:{' '} <input type="text" value={this.state.details} name="details" onChange={this.handleInputChange} />{' '} <br /> Content:{' '} <textarea value={this.state.content} name="content" cols="30" rows="10" onChange={this.handleInputChange} />{' '} <br /> <button onClick={this.handleClick(sid)}>TEST ME</button> </form> <button onClick={handleClose}>Close</button> {this.state.message && ( <div className="info">{this.state.message}</div> )} </div> </div> ) } } )都只会显示最后一个代码段ID。将ID推送到handleClick函数的过程也是如此,在该函数中我打算将ID与更新包结合在一起。

3 个答案:

答案 0 :(得分:1)

以下解决方案由HMR在评论中提出。

问题在于所有模态都在显示,而最后一个模态可见。 通过将模式从.map中移出,而是将ID从.map内更新为状态,然后将状态ID传递给模式中的新嵌套组件来解决。

还切换为使用动态CSS根据状态显示和隐藏模式。

Dashboard.jsx

export default class Snippets extends Component {
  constructor(props) {
    super(props)
    this.showModal = React.createRef()
    this.state = {
      snippets: [],
      show: false,
      sid: '',
    }
  }

  handleDelete = id => event => {
    event.preventDefault()
    api
      .deleteSnippet(id)
      .then(result => {
        console.log('DATA DELETED')
        api.getSnippets().then(result => {
          this.setState({ snippets: result })
          console.log('CLIENT UPDATED')
        })
      })
      .catch(err => this.setState({ message: err.toString() }))
  }
  handleModal = id => {
    this.setState({ sid: id })
    this.showModal.current.showModal()
  }
  //<div id="preview">{ReactHtmlParser(snippet.content)}</div>

  render() {
    return (
      <>
        <Modal ref={this.showModal} handleClose={this.hideModal}>
          <ModalUpdate sid={this.state.sid} />
        </Modal>
        <div className="Dashboard">
          <div className="wrapper">
            <div className="container">
              <div className="holder">
                <div className="content">
                  <div className="content__body">
                    <h3>Dashboard</h3>
                  </div>
                </div>
              </div>
              <div className="break"></div>
              {this.state.snippets.map(snippet => (
                <div key={snippet._id} className="holder--pod">
                  <div className="content">
                    <div className="content__snippet-preview">
                      Snippet preview
                    </div>
                    <div className="content__body">
                      <h4>{snippet.name}</h4>
                      <p>{snippet.details}</p>
                      <p>{snippet._id}</p>
                      <pre>
                        <code>{snippet.content}</code>
                      </pre>
                    </div>
                    <div className="content__button">
                      <button onClick={this.handleDelete(snippet._id)}>
                        Delete
                      </button>
                      <button
                        type="button"
                        onClick={() => this.handleModal(snippet._id)}
                      >
                        Open
                      </button>
                    </div>
                  </div>
                </div>
              ))}
            </div>
          </div>
        </div>
      </>
    )
  }


Modal.jsx

import React, { Component } from 'react'

export default class Modal extends Component {
  constructor(props) {
    super(props)
    this.state = {
      show: false,
    }
  }
  showModal = () => {
    this.setState({ show: true })
  }
  hideModal = () => {
    this.setState({ show: false })
  }

  render() {
    return (
      <div
        id="Modal"
        style={{ display: this.state.show === true ? 'flex' : 'none' }}
      >
        <div id="modal-main">
          <h4>Edit snippet </h4>
          {this.props.children}
          <button onClick={() => this.hideModal()}>Close</button>
        </div>
      </div>
    )
  }
}


ModalUpdate.jsx

import React, { Component } from 'react'

export default class ModalUpdate extends Component {
  constructor(props) {
    super(props)
    this.state = {
      name: '',
      details: '',
      content: '',
      message: null,
    }
  }
  // handleInputChange = event => {
  //   this.setState({
  //     [event.target.name]: event.target.value,
  //   })
  // }
  // handleClick = id => event => {
  //   event.preventDefault()
  //   console.log(id)
  // }

  render() {
    return <h4>ID = {this.props.sid}</h4>
  }
}

答案 1 :(得分:0)

我不确定handleDelete函数。但是更换线可能应该可以解决问题

<button onClick={() => this.handleDelete(snippet._id)}>

答案 2 :(得分:0)

一个潜在的问题是this.handleDelete(snippet._id)会立即触发,而不是onClick,因此您需要在事件监听器中添加一个匿名函数:

() => this.handleDelete(snippet._id)

代替

this.handleDelete(snippet._id)