Data binding in React

前端 未结 12 773
心在旅途
心在旅途 2021-01-30 19:49

What I want to do is when I type some text in an input field, it should appear in another place realtime.

Below is my input;



        
相关标签:
12条回答
  • 2021-01-30 20:41

    To be short, in React, there's no two-way data-binding.

    So when you want to implement that feature, try define a state, and write like this, listening events, update the state, and React renders for you:

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

    Details here https://facebook.github.io/react/docs/forms.html

    UPDATE 2020

    Note:

    LinkedStateMixin is deprecated as of React v15. The recommendation is to explicitly set the value and change handler, instead of using LinkedStateMixin.

    above update from React official site . Use below code if you are running under v15 of React else don't.

    There are actually people wanting to write with two-way binding, but React does not work in that way. If you do want to write like that, you have to use an addon for React, like this:

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

    Details here https://facebook.github.io/react/docs/two-way-binding-helpers.html

    For refs, it's just a solution that allow developers to reach the DOM in methods of a component, see here https://facebook.github.io/react/docs/refs-and-the-dom.html

    0 讨论(0)
  • 2021-01-30 20:42

    Some modules makes simpler data-binding in forms, for example:

    react-distributed-forms

    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

    It uses React context, so you don't have to wire together input in forms

    Here's a live demo

    0 讨论(0)
  • 2021-01-30 20:48

    With introduction of React hooks the state management (including forms state) became very simple and, in my opinion, way more understandable and predictable comparing with magic of other frameworks. For example:

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

    This one-way flow makes it trivial to understand how the data is updated and when rendering happens. Simple but powerful to do any complex stuff in predictable and clear way. In this case, do "two-way" form state binding.

    The example uses the primitive string value. Complex state management, eg. objects, arrays, nested data, can be managed this way too, but it is easier with help of libraries, like Hookstate (Disclaimer: I am the author of this library). Here is the example of complex state management.

    When a form grows, there is an issue with rendering performance: form state is changed (so rerendering is needed) on every keystroke on any form field. This issue is also addressed by Hookstate. Here is the example of the form with 5000 fields: the state is updated on every keystore and there is no performance lag at all.

    0 讨论(0)
  • 2021-01-30 20:51

    This could be achieved with a hook. However, I would not recommend it, as it strictly couples state and layout.

    November 2019 Data Bind with Hooks

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

    Use it in any functional component

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

    Basic version - bind value and 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>
            </>
        )
    }
    
    0 讨论(0)
  • 2021-01-30 20:52

    Define state attributes. Add universal handleChange event handler. Add name param to input tag for mapping.

    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}/>
    
    0 讨论(0)
  • 2021-01-30 20:52

    I think @Richard Garside is correct.

    I suggest some changes to clear even more the code.

    Change this

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

    To this

    onChange={this.handleOnChange}
    

    And also, change this

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

    To this

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

    Besides, you have to add the "name" attribute to the field with a value that relates with the key on the state object.

    0 讨论(0)
提交回复
热议问题