单击子组件按钮时卸载组件// React

时间:2017-10-27 10:37:51

标签: javascript reactjs meteor

我正在努力通过点击按钮成功删除组件。我在互联网上发现了类似的主题,但大多数都描述了如果在同一个组件中呈现所有内容的方法。在我的情况下,我在子组件中触发要删除的函数,并将此信息传递给父级,以便可以更改状态。但是我不知道如何提升特定组件的索引,这是一个问题 - 我相信。

有代码

PARENT COMPONENT



export class BroadcastForm extends React.Component {
  constructor (props) {
    super(props)
    this.state = {
      numberOfComponents: [],
      textMessage: ''
    }
    this.UnmountComponent = this.UnmountComponent.bind(this)
    this.MountComponent = this.MountComponent.bind(this)
    this.handleTextChange = this.handleTextChange.bind(this)
  }

  MountComponent () {
    const numberOfComponents = this.state.numberOfComponents
    this.setState({
      numberOfComponents: numberOfComponents.concat(
        <BroadcastTextMessageForm key={numberOfComponents.length} selectedFanpage={this.props.selectedFanpage}
          components={this.state.numberOfComponents}
          onTextChange={this.handleTextChange} dismissComponent={this.UnmountComponent} />)
    })
  }

  UnmountComponent (index) {
    this.setState({
      numberOfComponents: this.state.numberOfComponents.filter(function (e, i) {
        return i !== index
      })
    })
  }

  handleTextChange (textMessage) {
    this.setState({textMessage})
  }

  render () {
    console.log(this.state)
    let components = this.state.numberOfComponents
    for (let i = 0; i < components; i++) {
      components.push(<BroadcastTextMessageForm key={i} />)
    }
    return (
      <div>
        <BroadcastPreferencesForm selectedFanpage={this.props.selectedFanpage}
          addComponent={this.MountComponent}
          textMessage={this.state.textMessage} />

        {this.state.numberOfComponents.map(function (component) {
          return component
        })}
      </div>
    )
  }
}

export default withRouter(createContainer(props => ({
  ...props
}), BroadcastForm))
&#13;
&#13;
&#13;

儿童成分

&#13;
&#13;
import React from 'react'
import { createContainer } from 'react-meteor-data'
import { withRouter } from 'react-router'
import { BroadcastFormSceleton } from './BroadcastForm'

import './BroadcastTextMessageForm.scss'

export class BroadcastTextMessageForm extends React.Component {
  constructor (props) {
    super(props)
    this.handleChange = this.handleChange.bind(this)
    this.unmountComponent = this.unmountComponent.bind(this)
  }

  handleChange (e) {
    this.props.onTextChange(e.target.value)
  }

  unmountComponent (id) {
    this.props.dismissComponent(id)
  }

  render () {
    console.log(this.props, this.state)
    const textMessage = this.props.textMessage
    return (
      <BroadcastFormSceleton>
        <div className='textarea-container p-3'>
          <textarea id='broadcast-message' className='form-control' value={textMessage}
            onChange={this.handleChange} />
        </div>
        <div className='float-right'>
          <button type='button'
            onClick={this.unmountComponent}
            className='btn btn-danger btn-outline-danger button-danger btn-small mr-3 mt-3'>
            DELETE
          </button>
        </div>
      </BroadcastFormSceleton>

    )
  }
}

export default withRouter(createContainer(props => ({
  ...props
}), BroadcastTextMessageForm))
&#13;
&#13;
&#13;

我正在访问正确的组件并通过更改状态删除它。有任何想法如何实现它?

2 个答案:

答案 0 :(得分:1)

请在您的代码中修复以下问题。

  1. Do not mutate the state of the component。使用setState不可改变地改变状态。
  2. Do not use array index as the key for your component。尝试使用对于组件唯一的id字段。这也有助于识别您需要卸载的组件。

答案 1 :(得分:1)

尝试这样的事情。如前所述,您不希望使用数组索引作为键。

class ParentComponent extends React.Component {
  constructor() {
    this.state = {
      // keep your data in state, as a plain object
      textMessages: [
        {
          message: 'hello',
          id: '2342334', 
        },
        {
          message: 'goodbye!',
          id: '1254534',
        },
      ]
    };
    
    this.handleDeleteMessage = this.handleDeleteMessage.bind(this);
  }
  
  handleDeleteMessage(messageId) {
    // filter by Id, not index
    this.setState({
      textMessages: this.state.textMessages.filter(message => message.id !== messageId)
    })
  }
  
  render() {
    return (
      <div>
        {this.state.textMessages.map(message => (
          // Use id for key. If your data doesn't come with unique ids, generate them.
          <ChildComponent
            key={message.id}
            message={message}
            handleDeleteMessage={this.handleDeleteMessage}
          />
        ))}
      </div>
    )
  }
}

function ChildComponent({message,  handleDeleteMessage}) {

  function handleClick() {
    handleDeleteMessage(message.id)
  }
  
  return (
    <div>
      {message.message}
      <button
        onClick={handleClick}
      >
        Delete
      </button>
    </div>
  );
}