反应中的数据绑定

Cra*_*oiD 33 reactjs

嗨,我是新来的反应,我无法理解数据绑定如何在reactjs中工作.我在AngularJS中完成了数据绑定,但在reactjs中它似乎更复杂.

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

这是我的意见

<div className="post_input">

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

</div>
Run Code Online (Sandbox Code Playgroud)

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

Shu*_*tri 56

React中的数据绑定可以通过使用a来实现controlled input.通过将值绑定到a 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'));
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

  • @vsync使用箭头函数编写handleChange方法,箭头函数从其父级获取上下文,在本例中是反应组件类 (6认同)
  • 这不是很有效,箭头功能是动态的,并且在编译时将其移动到对象构造函数而不是原型中。因此,该组件的N个实例将生成N个函数,而不是1个。理想情况下,您应绑定到构造函数中,尽管这比较冗长。 (2认同)
  • @Omu,是的,您可以执行此操作,但是它的性能不是很好,因为它会在每个渲染器上创建一个新函数。构造函数中的绑定是首选模式 (2认同)

jiy*_*ong 12

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

因此,当您想要实现该功能时,请尝试定义a 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} />
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

详情请访问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')} />;
  }
});
Run Code Online (Sandbox Code Playgroud)

详情请访问https://facebook.github.io/react/docs/two-way-binding-helpers.html

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

  • Downvoted.你的第一句话就是居高临下并分散了重要的东西 - 答案. (2认同)
  • @ncubica @ Yoshiyahu 您可以根据需要编辑答案。我已经放弃回答问题了,因为 SO 是一个非常不友好的社区。失望的。 (2认同)
  • @jiyinyiyong不用担心.我希望你不要停止回答问题.人们并不意味着看起来很粗鲁,但我认为我们都可以更好地确保我们的答案,问题和评论措辞得当. (2认同)

And*_*rew 12

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

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

这种单向流程使得了解数据如何更新以及何时发生渲染变得微不足道。简单但功能强大,可以以可预测和清晰的方式完成任何复杂的事情。在这种情况下,请执行“双向”表单状态绑定。

该示例使用原始字符串值。复杂的状态管理,例如。对象、数组、嵌套数据也可以通过这种方式进行管理,但在库的帮助下更容易,比如Hookstate(免责声明:我是这个库的作者)。这是复杂状态管理的示例

当表单增长时,呈现性能会出现问题:表单状态在任何表单字段上的每次击键时都会更改(因此需要重新呈现)。Hookstate 也解决了这个问题。这是具有 5000 个字段的表单示例:状态在每个密钥库上更新,并且根本没有性能滞后。


Ric*_*ide 5

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

您可以使用 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'));
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)


Rod*_*igo 5

2022 年 1 月

使用钩子,您可以编写一个自定义组件,它完全可以满足您的需求。

我在下面的示例中使用了 TypeScript:

// InputBind.tsx

import {useState} from 'react';

export interface Binder {
    value: string;
    setter: (value: string) => void;
}

/**
 * Hook that returns a value to be used with InputBind component.
 */
export function useBind(initialValue: string): Binder {
    const [value, setter] = useState(initialValue);
    return {value, setter};
}

/**
 * Custom input component with binding.
 */
export function InputBind({value}: {value: Binder}) {
    return <input type="text" value={value.value}
        onChange={e => value.setter(e.target.value)} />;
}
Run Code Online (Sandbox Code Playgroud)

这是你如何使用它:

import {InputBind, useBind} from './InputBind';

function Foo() {
    const name = useBind('john');

    console.log('Value is', name.value);

    return (
        <div>
            <div>The name is {name.value}.</div>
            <InputBind value={name} />
        </div>
    );
}
Run Code Online (Sandbox Code Playgroud)

上面的例子非常简单。这个概念也可以扩展到其他input类型和select类型。