简体   繁体   中英

React.js - Setting a state item as an Array item, referencing in other state items then updating state when Array Item changes

Heres my question, if I update a state item which has been set to an Array item (array[0]) to another item in that Array (array[1]) and I've got other state items that are referencing that array, should react know that the other state items need to be updated?

If yes then why does my test below not work:

Class Decking extends React.Component  {

    constructor(props) {
        super(props)
        this.state = { 
            firstOption: props.product.acf.options.product_option[0],
            title: props.product.title,
        }

        this.state.product = {
            mainImage: {
                url: this.state.firstOption.image_gallery[0].source_url,
                alt: this.state.firstOption.image_gallery[0].alt_text,
            },
            thumbnails: this.state.firstOption.image_gallery,
            price: this.state.firstOption.price,
            dimensions: this.state.firstOption.dimensions,
            options: props.product.acf.options.product_option,
            desc: this.state.firstOption.description,
            spec: this.state.firstOption.size___length_spec
        }
    }

    toggleOptions(id) {
        const option = this.state.product.options[id]
        this.setState({firstOption: option})
    }

    render() {
        return (
           <div>
                <div className="flex flex-wrap">
                    <div className="w-1/2">
                        <img className="w-full shadow-xl" alt={this.state.product.mainImage.alt} src={this.state.product.mainImage.url} />
                        <div className="-ml-2">
                        {this.state.product.thumbnails.map((thumbnail, index) => (
                            <img className="w-16 border-solid border-3 border-blue-400 mx-2" key={index} src={thumbnail.source_url} alt={thumbnail.alt_text} />
                        ))}
                        </div>
                    </div>
                    <div className="w-1/2 pl-8">
                        <h1 className="text-4xl leading-normal">{this.state.title}</h1>
                        <div className="flex flex-wrap justify-between text-2xl mb-6">
                            <div className="font-light">
                            {this.state.product.dimensions}
                            </div>
                            <div className="font-light">
                            <b>Price:</b> {this.state.product.price}
                            </div>
                        </div>
                        <span className="text-xl font-light mb-4 block">Avaliable Options:</span>
                        <div className="flex flex-wrap mb-6 lg:mb-0">
                            {this.state.product.options.map((option, i) => (
                            <div className="w-full border-solid border-1 border-blue-400 shadow-lg flex items-center mb-4 px-5 py-4" key={i}>
                                <input onChange={e=>this.toggleOptions(e.target.id)} id={i} type="radio" /> <p className="checkChange mb-0 pl-4">{option.profileoption}</p>
                            </div>
                          ))}
                        </div>
                        <div className="w-full nomargin mb-4">
                            <b className="text-xl">Desc:</b>
                            <div dangerouslySetInnerHTML={{__html: this.state.product.desc}} />
                        </div>
                        <div className="w-full nomargin">
                            <b className="text-xl">Spec:</b>
                            <div dangerouslySetInnerHTML={{__html: this.state.product.spec}} />
                        </div>
                    </div>
                </div>
           </div>

        )
    }
}

I've set this.state.firstOption to an array item props.product.acf.options.product_option[0]

That item changes when my toggleOptions method gets called :

toggleOptions(id) {
    const option = this.state.product.options[id]
    this.setState({firstOption: option})
} 

And here is where the the method is called:

<div>
    {this.state.product.options.map((option, i) => (
        <div key={i}>
            <input onChange={e=>this.toggleOptions(e.target.id)} id={i} type="radio" /> <p>{option.profileoption}</p>
        </div>
     ))}
</div>

I hope I've made my question clear, I appreciate your attention :)

Within toggleOptions this will be undefined. To solve this you can bind the event handler in the constructor like this:

constructor( props ){
    super( props );
    this.toggleOptions = this.toggleOptions.bind(this);
  }

Or you could define toggleOptions as an arrow function like so:

const toggleOptions = (id) => {
    const option = this.state.product.options[id];
    this.setState({firstOption: option});
}

Using an arrow function automatically binds the scope of this to the function.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM