将道具传递给父组件

时间:2019-08-26 08:54:27

标签: reactjs react-props

我真的是React的新手,对此我一无所知。 我想将数据从NewAction组件传递到其父级NewActionSet。

我不知道我在想什么。

我正在开发一个包含很多组件的入门平台,我的目标是将输入到所有组件中的所有数据发送到服务器。

反应父组件:

import React from 'react'
import './NewActionSet.css'
import axios from 'axios'
import { Container, Segment, Header, Input } from 'semantic-ui-react'
import NewAction from './NewAction'
import 'bootstrap/dist/css/bootstrap.min.css'

class NewActionSet extends React.Component {
  constructor (props) {
    super(props)
    this.state = {
      actions: [],
      actionType: '',
      actionValue: '',
      creationStatus: undefined
        }
  }
  handleActions = value => {
    this.setState({
      actionsList: value
    })
    console.log(this.state.actionsList)
  }
  handleSubmit = event => {
    event.preventDefault()
    console.log(this.state)
    axios
      .post(
        '/assistant/actions/',
        { ...this.state.values },
        { headers: {
            xsrfHeaderName: 'X-CSRFToken',
            xsrfCookieName: 'csrftoken'
          },
          withCredentials: true
        }
      )
      .then(response => {
        console.log(response)
        this.setState({
          creationStatus: true
        })
      })
      .catch(error => {
        console.log(error)
        this.setState({
          creationStatus: false
        })
      })
  }
  addNewAction = () => {
    let { actions } = this.state
    this.setState({
      actions: [...actions, <NewAction onNewAction={this.handleActionstoParent} />]
    })
  }
  handleActionstoParent = (action2Value, selectedAction) => {
    this.setState({
      actionType : selectedAction,
      actionValue : action2Value
    })
// console.log(this.state.actionType, this.state.actiondValue)
  }
  renderActions () {
    return this.state.actions.map((action, index) => {
      return (
        <NewAction 
          key={index}
          type={this.props.actionType}
          content={action.content}
          onNewAction={this.handleActionstoParent}
        />
      )
    })
  }
  render () {
    let index = 0
    return (
      <Container>
        <Header> Action sets </Header>
        <Header color='grey' as='h3'>
          SET #{index + 1}
        </Header>
        {this.renderActions()}
        <button onClick={() => this.addNewAction()}> New Action </button>
      </Container>
    )
  }
}

export default NewActionSet

反应子组件

import React from 'react'
import './NewActionSet.css'
import { Header, Dropdown } from 'semantic-ui-react'
import NewSpeechText from './NewSpeechText'
import NewAddPageURL from './NewAddPageURL'
import 'bootstrap/dist/css/bootstrap.min.css'

class NewAction extends React.Component {
  constructor (props) {
    super(props)
    this.state = {
      availableActions: [
        { key: 1, text: 'Navigate to page', value: 'Navigate to page' },
        { key: 2, text: 'Play speech', value: 'Play speech' }
      ],
      selectedAction: '',
      actionValue: '',
      currentElement: ''
    }
  }
  handleActionURL = (value) => {
    this.setState({
      actionValue: value
    })
    console.log(this.state.selectedAction, this.state.actionValue)
  }
  handleActionSpeech = (value) => {
    this.setState({
      actionValue: value
    })
    console.log(this.state.selectedAction, this.state.actionValue)
  }
  // Props to pass data to parent component --> NewActionSet.js
  handleActionstoParent = (selected) => {
    var action2Value = this.state.actionValue;
    console.log(action2Value)
    var action2Type = this.state.actionType
    this.props.onNewAction(action2Value, action2Type)
    console.log(action2Type)
    // console.log(this.state.actionValue, this.state.selectedAction)
  }
  handleChange = (e, { value }) => {
    let element
    this.setState({
      selectedAction: value
    })
    if (value === 'Navigate to page') {
      element = <NewAddPageURL onNewAddPageURL={this.handleActionURL} onChange={this.handleActionstoParent()} />
    } else if (value === 'Play speech') {
      element = <NewSpeechText onNewSpeechText={this.handleActionSpeech} onChange={this.handleActionstoParent()} />
    }
    this.setState({
      currentElement: element
    })
  }
  render () {
    const { value } = this.state
    let index = 0
    return (
      <div className='action'>
        <div className='container'>
          <Header color='grey' as='h4'>
            ACTION #{index + 1}
          </Header>
          <div className='row'>
            <div className='col-md-4'>
              <Dropdown
                onChange={this.handleChange}
                options={this.state.availableActions}
                placeholder='Choose an action'
                selection
                value={value}
              />
            </div>
            <div className='col-md-4' />
            <div className='col-md-4' />
          </div>
          <div style={{ marginBottom: '20px' }} />
          {this.state.currentElement}
        </div>
      </div>
    )
  }
}

export default NewAction

可以请您帮忙吗?

非常感谢

3 个答案:

答案 0 :(得分:0)

NewAction组件中的handleActionstoParent函数是问题所在。 当您将数据从子级发送到父级时,实际上该数据不是更新的数据。

  // Props to pass data to parent component --> NewActionSet.js
  handleActionstoParent = (e) => {
    this.setState({ [e.target.name]: e.target.value }, () => {
      var action2Value = this.state.actionValue;
      var action2Type = this.state.actionType;
      this.props.onNewAction(action2Value, action2Type);
    });
  }

答案 1 :(得分:0)

您可以将函数传递给NewAction,在下面的示例中,我们将handleDataFlow函数传递给子组件,然后在子组件中使用它来传递更高的数据:

import React from 'react'
import './NewActionSet.css'
import { Header, Dropdown } from 'semantic-ui-react'
import NewSpeechText from './NewSpeechText'
import NewAddPageURL from './NewAddPageURL'
import 'bootstrap/dist/css/bootstrap.min.css'

class NewAction extends React.Component {
  constructor (props) {
    super(props)
    this.state = {
      availableActions: [
        { key: 1, text: 'Navigate to page', value: 'Navigate to page' },
        { key: 2, text: 'Play speech', value: 'Play speech' }
      ],
      selectedAction: '',
      actionValue: '',
      currentElement: ''
    }
  }
  handleActionURL = (value) => {
    this.setState({
      actionValue: value
    })
    console.log(this.state.selectedAction, this.state.actionValue)
  }
  handleActionSpeech = (value) => {
    this.setState({
      actionValue: value
    })
    console.log(this.state.selectedAction, this.state.actionValue)
  }
  // Props to pass data to parent component --> NewActionSet.js
  handleActionstoParent = (selected) => {
    var action2Value = this.state.actionValue;
    console.log(action2Value)
    var action2Type = this.state.actionType
    this.props.onNewAction(action2Value, action2Type)
    console.log(action2Type)
    // console.log(this.state.actionValue, this.state.selectedAction)
  }
  handleChange = (e, { value }) => {
    let element
    this.setState({
      selectedAction: value
    })

    this.props.handleDataFlow(value)

    if (value === 'Navigate to page') {
      element = <NewAddPageURL onNewAddPageURL={this.handleActionURL} onChange={this.handleActionstoParent()} />
    } else if (value === 'Play speech') {
      element = <NewSpeechText onNewSpeechText={this.handleActionSpeech} onChange={this.handleActionstoParent()} />
    }
    this.setState({
      currentElement: element
    })
  }
  render () {
    const { value } = this.state
    let index = 0
    return (
      <div className='action'>
        <div className='container'>
          <Header color='grey' as='h4'>
            ACTION #{index + 1}
          </Header>
          <div className='row'>
            <div className='col-md-4'>
              <Dropdown
                onChange={this.handleChange}
                options={this.state.availableActions}
                placeholder='Choose an action'
                selection
                value={value}
              />
            </div>
            <div className='col-md-4' />
            <div className='col-md-4' />
          </div>
          <div style={{ marginBottom: '20px' }} />
          {this.state.currentElement}
        </div>
      </div>
    )
  }
}

export default NewAction

答案 2 :(得分:0)

React中的数据流是单向的。数据只有一种传输方式:从父级到子级。 要从孩子那里更新父状态,您必须发送动作(以道具形式)。

<NewAction updateParentState={this.doSmth} />
...
const doSmth = params => { this.setState({ ... })

在NewAction中,您可以在特定情况下调用它

let parentUpdateState = ....
this.props.updateParentState(parentUpdateState);