2017-04-19 34 views
0

我有以下两个组件应用程序和它的孩子工具栏得到的价值的投入和给父母在反应

工具栏包含一个表单和输入,我想将输入值直到应用程序组件的状态 - 但只有当用户确认它(在提交或输入等)时。

我目前的尝试不工作,因为我只得到一个代理和一个事件对象(这是有道理的)。我将如何做到这一点?

我没有使用Redux或类似的东西。

App.js

import React, {Component} from 'react' 
import {render} from 'react-dom' 
import {} from './styles/base.scss' 

import ImageContainer from './components/Images' 
import Toolbar from './components/Toolbar' 

export default class App extends Component { 
    constructor(props) { 
     super(props); 
     // http://www.cloudypoint.com/Tutorials/discussion/javascript-how-to-update-parents-state-in-react/ 
     this.setFolderPathHandler = this.setFolderPathHandler.bind(this); 
    } 

    setFolderPathHandler(e) { 
     e.preventDefault(); 
     console.log(arguments); 
     // this.setState({ 
     //  xyz: input 
     // }); 
    } 

    render() { 
     return (
      <div> 
       <Toolbar setFolderPathHandler={this.setFolderPathHandler} /> 
       <ImageContainer /> 
      </div> 
     ) 
    } 
} 

工具栏/ index.js

import React, { Component } from 'react'; 
import path from 'path'; 

class Toolbar extends Component { 
    render() { 
     return (
      <nav className="toolbar"> 
       <div className="column"> 
        {/* START used to be it's own component */} 
        <form onSubmit={this.props.setFolderPathHandler}> 
         <div className="form-field"> 
          <input type="text" className="folder-path" ref={(input) => this.input = input} /> 
          <button><i className="fa fa-fw fa-2x fa-folder-open" aria-hidden="true"></i></button> 
         </div> 
        </form> 
        {/* END used to be it's own component */} 
       </div> 
       <div className="column"> 
        <button><i className="fa fa-fw fa-2x fa-chevron-left" aria-hidden="true"></i></button> 
        <button><i className="fa fa-fw fa-2x fa-chevron-right" aria-hidden="true"></i></button> 
       </div> 
      </nav> 
     ); 
    } 
} 

export default Toolbar; 

我确实有输入作为一个单独的组件,但它是太混乱,我(我是新反应)。

+0

“.folder-path”是你关心的输入吗?如果我们将整个组件缩减为一个元素(也可能是一个包装),它会是同一个问题吗?它使得它更容易接近(和复制) –

+0

我认为你应该改变onSummit方法,像这样:'onSubmit = {()=> this.props.setFolderPathHandler()}'。这个想法是执行父母的方法 –

回答

1

App.js

import React, {Component} from 'react' 
import {render} from 'react-dom' 
import {} from './styles/base.scss' 

import ImageContainer from './components/Images' 
import Toolbar from './components/Toolbar' 

export default class App extends Component { 
    constructor(props) { 
     super(props); 
     // http://www.cloudypoint.com/Tutorials/discussion/javascript-how-to-update-parents-state-in-react/ 
     this.setFolderPathHandler = this.setFolderPathHandler.bind(this); 
    } 

    setFolderPathHandler(inputValue) { 
     // this.setState({ 
     //  xyz: inputValue 
     // }); 
    } 

    render() { 
     return (
      <div> 
       <Toolbar setFolderPathHandler={this.setFolderPathHandler} /> 
       <ImageContainer /> 
      </div> 
     ) 
    } 
} 

工具栏/ index.js

import React, { Component } from 'react'; 
import path from 'path'; 

class Toolbar extends Component { 

    constructor(props) { 
     super(props); 
     this.submit = this.submit.bind(this); 
    } 

    submit(event) { 
     event.preventDefault(); 
     this.props.setFolderPathHandler(this.input.value); 
    } 

    render() { 
     return (
      <nav className="toolbar"> 
       <div className="column"> 
        {/* START used to be it's own component */} 
        <form onSubmit={this.submit.bind(this)}> 
         <div className="form-field"> 
          <input type="text" className="folder-path" ref={(input) => this.input = input} /> 
          <button><i className="fa fa-fw fa-2x fa-folder-open" aria-hidden="true"></i></button> 
         </div> 
        </form> 
        {/* END used to be it's own component */} 
       </div> 
       <div className="column"> 
        <button><i className="fa fa-fw fa-2x fa-chevron-left" aria-hidden="true"></i></button> 
        <button><i className="fa fa-fw fa-2x fa-chevron-right" aria-hidden="true"></i></button> 
       </div> 
      </nav> 
     ); 
    } 
} 

export default Toolbar; 
+0

这工作!我必须对它进行一些修改:需要有一个具有'super(props)'和'this.submit = this.submit.bind(this);'的构造函数。另外,我不得不将'this.input.val()'更改为'this.input.value'。如果你也可以修改这些,我会将其标记为答案:) – atwright147

+0

完成了,感谢你的反馈。 –

1

首先,如果你想跟踪工具栏输入值,你应该把它保存到state

class Toolbar extends Component { 
    constructor(...args) { 
     super(...args) 

     this.state = {text: ''}; 
    } 

    onTextChange(event) { 
     const text = event.target.value; 
     this.setState({text}); 
    } 

    onSubmit(event) { 
     event.preventDefault(); 

     this.props.setFolderPathHandler(this.state.text); 
    }   

    render() { 
     return (
      <nav className="toolbar"> 
       <div className="column"> 
        <form onSubmit={this.onSubmit.bind(this)}> 
         <div className="form-field"> 
          <input type="text" className="folder-path" value={this.state.text} onChange={this.onTextChange.bind(this)} /> 
          <button><i className="fa fa-fw fa-2x fa-folder-open" aria-hidden="true"></i></button> 
         </div> 
        </form> 
       </div> 
       ... 
      </nav> 
     ); 
    } 
} 

export default Toolbar; 

请注意,我们正在内部保留input的值,并且我们不会将本机事件传递给父控制器。

然后在父控制器:

setFolderPathHandler(input) { 
    // do something with the input 
} 

这种解决方案具有,除非成分从DOM移除和再次加入不能从父组件复位的输入值的问题。

这通常通过将state添加到父组件来解决。父母可以将textonChange处理程序传递给包含<input>的孩子,或者父母可以创建<input>并将其作为属性传递给子组件。试想一下:

class Toolbar extends Component { 
    render() { 
     return (
      <nav className="toolbar"> 
       <div className="column"> 
        <form onSubmit={this.props.onSubmit}> 
         <div className="form-field"> 
          {this.props.textInput} 
          <button><i className="fa fa-fw fa-2x fa-folder-open" aria-hidden="true"></i></button> 
         </div> 
        </form> 
       </div> 
       ... 
      </nav> 
     ); 
    } 
} 

App

export default class App extends Component { 
    ... 

    render() { 
     const textInput = (
      <input ... value={this.state.text} onChange={this.onTextChange} /> 
     ); 

     return (
      <div> 
       <Toolbar onSubmit={this.onSubmit} textInput={textInput} /> 
       <ImageContainer /> 
      </div> 
     ) 
    } 
} 

这使得分离是处理业务逻辑组件(具有状态,智能组件)和组件,只有现在的事(无状态的,愚蠢的组件)。