Jon Harding
Jon Harding

Reputation: 4946

pass event and object to function in react

I'm new to react trying to implement Redux I'm trying to update state when a text-input gets updated. I'm able to extract the e.target.value but it also needs to be aware of what object was changed

For example my data might be something like:

{ name: 'Penny', namePlural: 'Pennies', label: '1¢', value: .01, sum: 0 },
{ name: 'Nickel', namePlural: 'Nickels', label: '5¢', value: .05, sum: 0 },
{ name: 'Dime', namePlural: 'Dimes', label: '10¢', value: .10, sum: 0 },
{ name: 'Quarter', namePlural: 'Quarters', label: '25¢', value: .25, sum: 0 }

I need to update the sum for a particular denomination.

Here is what I have for my presentation component

import React, { Component } from 'react';
import PropTypes from 'prop-types';

class DenomInput extends Component {
    constructor(props) {
        super(props);
        this.state = {
            denom: props.denom
        }
    }

    handleKeyUp = (e) => {
        this.props.onDenomChange(e.target.value);
    }

    render() {
        return (
            <div className="input-group denom">
                <span className="input-group-addon">{this.state.denom.label}</span>
                <input
                    type="text"
                    className="form-control"
                    onChange={this.handleKeyUp}
                    value={this.state.denom.sum} />

                <span className="input-group-addon">{this.state.denom.count | 0}</span>
            </div>
        );
    }
}

DenomInput.PropTypes = {
    denom: PropTypes.object.isRequired
}

export default DenomInput;

With this I'm able to get the value of the input field, but how could I pass up which denomination I'm currently on as well?

Upvotes: 0

Views: 6352

Answers (2)

djfdev
djfdev

Reputation: 6037

Mayank's comment is correct, you can modify your props.onDenomChange function to accept a denom as the second argument. But in order for your handleKeyUp function to access component state, you'll need to explicitly bind the handler. So your input JSX should look like this:

<input
  type="text"
  className="form-control"
  onChange={this.handleKeyUp.bind(this)}
  value={this.state.denom.sum} />

Upvotes: 1

Leonid Lazaryev
Leonid Lazaryev

Reputation: 326

On first place, i would recommend you to avoid state at all, but if you want to keep it don't forget to update state after receiving new properties.

Assuming you want to change just sum property:

import React, { Component } from 'react';
import PropTypes from 'prop-types';

class DenomInput extends Component {
    constructor(props) {
        super(props);
        this.state = {
            denom: props.denom
        }
    }

    componentWillReceiveProps(nextProps){
        const {denom} = nextProps;
        this.setState({denom});
    }

    handleKeyUp = (e) => {
        const {denom} = Object.assign({}, this.state);
        denom.sum = e.target.value;
        this.props.onDenomChange(denom);
    }

    render() {
        return (
            <div className="input-group denom">
                <span className="input-group-addon">{this.state.denom.label}</span>
                <input
                    type="text"
                    className="form-control"
                    onChange={this.handleKeyUp}
                    value={this.state.denom.sum} />

                <span className="input-group-addon">{this.state.denom.count | 0}</span>
            </div>
        );
    }
}

DenomInput.PropTypes = {
    denom: PropTypes.object.isRequired
}

export default DenomInput;

And if you want to change several properties:

import React, { Component } from 'react';
import PropTypes from 'prop-types';

class DenomInput extends Component {
    constructor(props) {
        super(props);
        this.state = {
            denom: props.denom
        }
    }

    componentWillReceiveProps(nextProps){
        const {denom} = nextProps;
        this.setState({denom});
    }

    handleKeyUp = (e) => {
        const {denom} = Object.assign({}, this.state);
        denom[e.target.name] = e.target.value;
        this.props.onDenomChange(denom);
    }

    render() {
        return (
            <div className="input-group denom">
                <span className="input-group-addon">{this.state.denom.label}</span>
                <input
                    type="text"
                    className="form-control"
                    onChange={this.handleKeyUp}
                    name='sum'
                    value={this.state.denom.sum} />
                <input
                    type="text"
                    className="form-control"
                    onChange={this.handleKeyUp}
                    name='value'
                    value={this.state.denom.value} />

                <span className="input-group-addon">{this.state.denom.count | 0}</span>
            </div>
        );
    }
}

DenomInput.PropTypes = {
    denom: PropTypes.object.isRequired
}

export default DenomInput;

Upvotes: 0

Related Questions