反应中的数据绑定

时间:2017-02-14 03:51:08

标签: reactjs

嗨,我是新手,我很难理解数据绑定在reactjs中是如何工作的。我在AngularJS中完成了数据绑定,但在reactjs中它似乎更复杂。

我想要做的是当我在输入字段中输入一些文本时,它应该实时出现在另一个地方。

这是我的输入

<div className="post_input">

    <input className='post_data_input_overlay' placeholder="Ask your question here" ref="postTxt"/>

</div>

所以当我在这个输入字段中输入内容时,它应该出现在其他地方。我该怎么做?

12 个答案:

答案 0 :(得分:35)

React中的数据绑定可以使用controlled input来实现。通过将值绑定到state variableonChange事件来实现受控输入,以在输入值更改时更改状态。

请参阅以下代码段

class App extends React.Component {
  constructor() {
    super();
    this.state = {value : ''}
  }
  handleChange = (e) =>{ 
    this.setState({value: e.target.value});
  }
  render() {
    return (
    <div>
        <input type="text" value={this.state.value} onChange={this.handleChange}/>
        <div>{this.state.value}</div>
    </div>
   )
  }
}
ReactDOM.render(<App/>, document.getElementById('app'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.js"></script>
<div id="app"></div>

答案 1 :(得分:9)

简而言之,在React中,没有双向数据绑定。

因此,当您想要实现该功能时,请尝试定义state,然后像这样写,监听事件,更新状态,并为您执行React渲染:

class NameForm extends React.Component {
  constructor(props) {
    super(props);
    this.state = {value: ''};

    this.handleChange = this.handleChange.bind(this);
  }

  handleChange(event) {
    this.setState({value: event.target.value});
  }

  render() {
    return (
      <input type="text" value={this.state.value} onChange={this.handleChange} />
    );
  }
}

此处详细信息https://facebook.github.io/react/docs/forms.html

实际上有些人想要用双向绑定来编写,但React不能以这种方式工作。如果你想这样写,你必须使用React的插件,如下所示:

var WithLink = React.createClass({
  mixins: [LinkedStateMixin],
  getInitialState: function() {
    return {message: 'Hello!'};
  },
  render: function() {
    return <input type="text" valueLink={this.linkState('message')} />;
  }
});

此处详细信息https://facebook.github.io/react/docs/two-way-binding-helpers.html

对于refs,它只是一个允许开发人员在组件方法中访问DOM的解决方案,请参阅此处https://facebook.github.io/react/docs/refs-and-the-dom.html

答案 2 :(得分:3)

要将控件绑定到您的状态,您需要在组件上调用一个函数,该函数从控件的事件处理程序更新状态。

您可以使用ES6计算名称功能创建一个通用更新函数,并将控件内嵌所需的值传递给控件,​​而不是拥有所有表单域的更新函数:

class LovelyForm extends React.Component {
  constructor(props) {
  alert("Construct");
    super(props);
    this.state = {
      field1: "Default 1",
      field2: "Default 2"
    };
  }

  update = (name, e) => {
    this.setState({ [name]: e.target.value });
  }

  render() {
    return (
      <form>
        <p><input type="text" value={this.state.field1} onChange={(e) => this.update("field1", e)} />
          {this.state.field1}</p>
        <p><input type="text" value={this.state.field2} onChange={(e) => this.update("field2", e)} />
          {this.state.field2}</p>
      </form>
    );
  }
}
ReactDOM.render(<LovelyForm/>, document.getElementById('example'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="example"></div>

答案 3 :(得分:2)

随着React hooks的引入,状态管理(包括表单状态)变得非常简单,在我看来,与其他框架的魔力相比,状态管理更加易懂和可预测。例如:

const MyComponent = () => {
    const [value, setValue] = React.useState('some initial value');
    return <input value={value} onChange={e => setValue(e.target.value)} />;
}

这种单向流程使您很容易理解如何更新数据以及何时进行渲染。简单但功能强大,以可预测和清晰的方式完成任何复杂的工作。在这种情况下,请执行“双向”表单状态绑定。

该示例使用原始字符串值。复杂的状态管理,例如对象,数组,嵌套数据也可以通过这种方式进行管理,但是在react-use-state-x之类的库的帮助下更容易(免责声明:我是该库的作者)。例如(从react-use-state-x文档复制):

const BookEditorExample = (props: { book: { title: string, popularity: number } }) => {
    // note we obtain nested links straight away
    const links = useStateLink(props.book).nested;
    return (
        <div>
            <label>Title</label>
            <input
                value={links.title.value}
                onChange={e => links.title.set(e.target.value)}
            />
            <label>Popularity</label>
            <input
                value={links.popularity.value}
                onChange={e => links.popularity.set(Number(e.target.value))}
            />
        </div>
    );
};

答案 4 :(得分:1)

  

实际上有些人想用双向绑定来编写,但是React无法以这种方式工作。

是的,有些人想编写双向数据绑定。从根本上说,React阻止他们这样做根本没有错。不过,我不建议他们为此使用过时的React mixin。因为使用third-party packages看起来更好。

import { LinkedComponent } from 'valuelink'

class Test extends LinkedComponent {
    state = { a : "Hi there! I'm databinding demo!" };

    render(){
        // Bind all state members...
        const { a } = this.linkAll();

        // Then, go ahead. As easy as that.
        return (
             <input type="text" ...a.props />
        )
    }
}

问题是双向数据绑定是React中的设计模式。 Here's my article with a 5-minute explanation on how it works

答案 5 :(得分:1)

  

这可以通过挂钩来实现。但是,我不建议这样做,因为它严格将状态和布局结合在一起。

2019年11月数据与钩子绑定

const useInput = (placeholder, initial) => {
    const [value, setVal] = useState(initial)
    const onChange = (e) => setVal(e.target.value)
    const element = <input value={value} onChange={onChange} placeholder={placeholder}/>
    return {element, value}
}

在任何功能组件中使用它

const BensPlayGround = () => {
    const name = useInput("Enter name here")
    return (
        <>
            {name.element}
            <h1>Hello {name.value}</h1>
        </>
    )
}

基本版本-绑定值和onChange

const useDataBind = () => {
    const [value, setVal] = useState("")
    const onChange = (e) => setVal(e.target.value)
    return {value, onChange}
}

const Demo = (props) => {
    const nameProps = useDataBind()
    return (
        <>
            <input {...nameProps} placeholder="Enter name here" />
            <h1>Hello {nameProps.value}</h1>
        </>
    )
}

答案 6 :(得分:0)

class App extends React.Component {
  constructor() {
    super();
    this.state = {value : ''}
  }
  handleChange = (e) =>{ 
    this.setState({value: e.target.value});
  }
  render() {
    return (
    <div>
        <input type="text" value={this.state.value} onChange={this.handleChange}/>
        <div>{this.state.value}</div>
    </div>
   )
  }
}
ReactDOM.render(<App/>, document.getElementById('app'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.js"></script>
<div id="app"></div>

答案 7 :(得分:0)

某些模块可以简化表单中的数据绑定,例如:

反应分布形式

class SomeComponent extends React.Component {
  state = {
    first_name: "George"
  };

  render() {
    return (
      <Form binding={this}>
        <Input name="first_name" />
      </Form>
    );
  }
}

https://www.npmjs.com/package/react-distributed-forms#data-binding

它使用React上下文,因此您不必将表单中的输入连接在一起

Here's a live demo

答案 8 :(得分:0)

无需在react.js中用setState()打破头脑

React-chopper创建的新图书馆

类似于 reactjs

中的 angularjs 的代码

reactjs

中没有 setState 的代码

浏览示例以获取更多说明

import React, { Component } from 'react';
import { render } from 'react-dom';
import Rcp from 'react-chopper';

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      name: 'React'
    };
    this.modal = Rcp(this.state, this);
  }

  tank = () => {
    console.log(this.modal)
  }
  render() {
    return (
      <div>
        <input value={this.modal.name} onChange={e => this.modal.name = e.target.value} />
        <p> Bang Bang {this.modal.name} </p>
        <button onClick={() => this.tank()}>console</button>
      </div>
    );
  }
}

render(<App />, document.getElementById('root'));

评论,欢迎PR ...享受

答案 9 :(得分:0)

使用React团队的Hooks新功能,该功能使功能组件能够处理状态更改。.您的问题可以轻松解决

import React, { useState, useEffect } from 'react'
import ReactDOM from 'react-dom';

const Demo = props =>{
    const [text, setText] = useState("there");
    return props.logic(text, setText);
};

const App = () => {
    const [text, setText] = useState("hello");

    const componentDidMount = () =>{
        setText("hey");
    };
    useEffect(componentDidMount, []);

    const logic = (word, setWord) => (
        <div>
            <h1>{word}</h1>
            <input type="text" value={word} onChange={e => setWord(e.target.value)}></input>
            <h1>{text}</h1>
            <input type="text" value={text} onChange={e => setText(e.target.value)}></input>
        </div>
    );
    return <Demo logic={logic} />;
};

ReactDOM.render(<App />,document.getElementById("root"));

答案 10 :(得分:0)

定义状态属性。添加通用的handleChange事件处理程序。在输入标签中添加名称参数以进行映射。

this.state = { stateAttrName:"" }

handleChange=(event)=>{
    this.setState({[event.target.name]:event.target.value });
  } 

<input className="form-control" name="stateAttrName" value= 
{this.state.stateAttrName} onChange={this.handleChange}/>

答案 11 :(得分:0)

我认为@Richard Garside是正确的。

我建议您进行一些更改以清除更多代码。

更改此

onChange={(e) => this.update("field2", e)}

对此

onChange={this.handleOnChange}

此外,更改此

this.setState({ [name]: e.target.value });

对此

this.setState({ [e.target.name]: e.target.value})

此外,您必须将“名称”属性添加到具有与状态对象上的键相关的值的字段。