获取输入值并在React

时间:2017-04-19 19:50:40

标签: reactjs

我有以下两个组件 App 及其子工具栏

工具栏包含一个表单和输入,我想将值从输入传递到App组件的状态 - 但仅在用户确认它时(在提交或输入等)。

我当前的尝试不起作用,因为我只获得一个代理和一个事件对象(这确实有意义)。我该怎么做?

我没有使用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;

我确实将输入作为一个单独的组件,但它对我来说太混乱了(我是React的新手)。

2 个答案:

答案 0 :(得分: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;

答案 1 :(得分:1)

首先,如果要跟踪工具栏中的输入值,则应将其保存到QtQuick.Controls 2.x

contentX/Y

请注意,我们在内部保留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;

此解决方案存在以下问题:除非从DOM中删除组件并再次添加,否则无法从父组件重置输入值。

这通常通过将input放入父组件来解决。然后,父级可以将setFolderPathHandler(input) { // do something with the input } state处理程序传递给包含text的子级,或者父级可以创建onChange并将其作为属性传递给子组件。考虑:

<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>
        );
    }
}

这允许分离处理业务逻辑的组件(具有状态,智能组件)和仅呈现事物的组件(无状态,哑组件)。