1

I'm new to React and still pretty new to programming in general and I've been practicing a bit just to get the basics down.

I currently have this:

class App extends Component {
  constructor(props){
    super(props);

		this.state={strings: [], 
			  textAreas: [<TextareaComponent ref='index0' onInput={this.onInputHandler} />, 
			  <TextareaComponent ref='index1' onInput={this.onInputHandler} />]};

	   this.onInputHandler = this.onInputHandler.bind(this);
	}

	

	onInputHandler(){
		const stringsArray = this.refs['index1'].refs.content.value.split(/\r|\n/);
		this.setState({strings: (stringsArray)});
	}

	

	render(){
		console.log(this.state.textAreas);
		const renderTextareas = this.state.textAreas.map((textArea, index) => {
	 		return <div key={index}>{textArea}</div>
		})
		return(
	 		<div>
	 			{renderTextareas}
	 		</div>
		);
	}
};

class TextareaComponent extends Component {
	constructor(props){
		super(props);
	}

	render(){
		return(
	 		<div>
	 			<textarea ref='content' onChange={this.props.onInput}></textarea>
	 		</div>
		);
	}
};

Right now, my plan is to add a button that would push a new TextareaComponent to the textAreas array to render an additional textarea to the DOM. Currently I've just set the 2nd textarea as the element that I'd like to get values from.

Everything appears on the screen, but my problem is that I get this error when I type on any of the textareas that were rendered: Uncaught TypeError: Cannot read property 'index1' of undefined.

I noticed that when I just directly place the Textarea component with a ref of 'index1' on the parent component, the console logs the values properly and it seems to be able to read the 'index1' property. I'm not really sure where I'm getting it wrong.

Thanks in advance

1
  • 1
    This doesn't directly answer your question, but it is probably a bad idea to put React elements inside your state like that. As you say, if you take them out of state and put them in render(), it works fine. You should keep "plain" values in your state, and only in render() use JSX to turn your state into elements. Commented Mar 9, 2017 at 5:58

1 Answer 1

1

You need to bind the onInputHandler function while passing it as a prop to the TextareaComponent component

class App extends Component {
  constructor(props){
    super(props);

		this.state={strings: [], 
			  textAreas: [<TextareaComponent ref='index0' onInput={this.onInputHandler.bind(this)} />, 
			  <TextareaComponent ref='index1' onInput={this.onInputHandler.bind(this)} />]};

	   this.onInputHandler = this.onInputHandler.bind(this);
	}

	

	onInputHandler(){
		const stringsArray = this.refs['index1'].refs.content.value.split(/\r|\n/);
		this.setState({strings: (stringsArray)});
	}

	

	render(){
		console.log(this.state.textAreas);
		const renderTextareas = this.state.textAreas.map((textArea, index) => {
	 		return <div key={index}>{textArea}</div>
		})
		return(
	 		<div>
	 			{renderTextareas}
	 		</div>
		);
	}
};

class TextareaComponent extends Component {
	constructor(props){
		super(props);
	}

	render(){
		return(
	 		<div>
	 			<textarea ref='content' onChange={this.props.onInput}></textarea>
	 		</div>
		);
	}
};

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.