I am following a tutorial and cannot get the following code to run. When I run the following code I get the error Can't add property attachToForm, object is not extensible
. Are you no longer to allowed to change child props in this way (ie. with child.props.key = value)? If not can you see a better way of adding a function to nested children only if the element is an input?
React.Children.forEach(children, function (child) { if (child.props.name) { child.props.attachToForm = this.attachToForm; child.props.detachFromForm = this.detachFromForm; } if (child.props.children) { this.registerInputs(child.props.children); } }.bind(this));
I am using es6 if that changes anything but the tutorial can be found here: http://christianalfoni.github.io/javascript/2014/10/22/nailing-that-validation-with-reactjs.html
FormComponent:
'use strict'; import React from 'react'; import BaseComponent from '@client/base-component'; export default class Form extends BaseComponent { constructor(props) { super(props); this.state = {}; } render() { var classString = this.props.className ? this.props.className : ''; var classArray = ['_common-form', this.props.type ? 'form--' + this.props.type : 'form--basic' ]; for(var i = 0; i < classArray.length; i++){ if(classArray[i]){ classString = classString + ' ' +classArray[i]; } } var props = { type: this.props.type, className: classString, style: this.props.style, onSubmit: this.props.onSubmit }; return React.createElement( 'form', props, this.newChildren ); } componentWillMount() { this.inputs = {}; this.model = {}; this.newChildren = []; this.registerInputs(this.props.children); } registerInputs(children) { React.Children.forEach(children, function (child) { if (child.props.name) { child.props.attachToForm = this.attachToForm; child.props.detachFromForm = this.detachFromForm; } if (child.props.children) { this.registerInputs(child.props.children); } }.bind(this)); } attachToForm(component) { this.inputs[component.props.name] = component; this.model[component.props.name] = component.state.value; } detachFromForm(component) { delete this.inputs[component.props.name]; delete this.model[component.props.name]; } }
ModalComponent:
'use strict'; import React from 'react'; import Modal from '@client/common/modal'; import Button from '@client/common/buttons'; import AddParticipant from './add_participant'; import Form from '@client/common/form_elements'; import Input from '@client/common/form_elements/input.js'; import SlideToggle from '@client/common/form_elements/slide_toggle.js'; import FormField from '@client/common/form_elements/form_field.js'; import FormSection from '@client/common/form_elements/section.js'; import BaseComponent from '@client/base-component'; export default class EditTeam extends BaseComponent { constructor(props) { super(props); this.state = { values: { name: props.team.name, mission: props.team.mission, globalSearch: props.team.globalSearch, public: props.team.public, witcryptSecured: props.team.witcryptSecured }, addParticipantModal: false }; } render() { var participantsList = []; this.props.team.participants.forEach(function(participant) { participantsList.push( <div className="participant" key={participant.key}> <span className="participant-avatar" style={{backgroundImage:`url("${participant.avatar}")`}}></span> <span>{participant.name}</span> <span className={`${participant.roll}-action roll`}>{participant.roll}<a></a></span> </div> ); }.bind(this)); return ( <Modal className="_common-edit-team-settings" title={`Edit ${this.props.team.name}`} isOpen={this.props.modalIsOpen && this.props.editTeamModal} onCancel={this.props.toggleEditTeamModal} backdropClosesModal> <Form onSubmit={this.saveChanges}> <FormSection className="edit-team-details" sectionHeader="Team Details"> <FormField label="Name"> <Input name="name" value={this.state.values.name} onChange={this.handleInputChange} type="text" placeholder={this.props.team.name}/> </FormField> <FormField label="Mission"> <Input name="mission" value={this.state.values.mission} onChange={this.handleInputChange} type="text" placeholder={this.props.team.kitMission || 'Kit Mission'} multiline /> </FormField> </FormSection> <FormSection className="privacy-settings" sectionHeader="Privacy Settings"> <FormField label="Included in global search results" > <SlideToggle name="globalSearch" defaultChecked={this.state.values.globalSearch} onChange={this.handleCheckedChange} type="checkbox" /> </FormField> <FormField label="Accessible by anyone" > <SlideToggle name="public" defaultChecked={this.state.values.public} onChange={this.handleCheckedChange} type="checkbox" /> </FormField> <FormField label="Secured with WitCrypt" > <SlideToggle name="witcryptSecured" defaultChecked={this.state.values.witcryptSecured} onChange={this.handleCheckedChange} type="checkbox" /> </FormField> </FormSection> <FormSection sectionHeader="Participants"> {participantsList} <div id="add-participant" className="participant" onClick={this.toggleAddParticipantModal}> <span className="participant-avatar" style={{backgroundImage:'url(/img/blue_add.svg)'}}></span> <span>Add a Participant</span> <span className="add-action roll"><a></a></span> </div> </FormSection> <Button type="hollow-primary" size="md" className="single-modal-btn" block submit>Save</Button> </Form> <AddParticipant people={this.props.people} toggleAddParticipantModal={this.props.toggleAddParticipantModal} modalIsOpen={this.props.modalIsOpen} toggleAddParticipantModal={this.toggleAddParticipantModal} addParticipantModal={this.state.addParticipantModal} /> </Modal> ); } toggleAddParticipantModal() { this.setState({ addParticipantModal: !this.state.addParticipantModal }); } handleCheckedChange(event){ var newState = this.state; newState.values[event.target.name] = !newState.values[event.target.name]; this.setState( newState ); } handleInputChange(event){ var newState = this.state; newState.values[event.target.name] = event.target.value; this.setState( newState ); } saveChanges(e){ e.preventDefault(); } }
Are you using React v.14 or above? the props object is now frozen and cant be changed. You can use React.cloneElement
instead
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With