如果我点击一个特定的ToDos编辑按钮,它的值应该在textarea内默认,但每次最后一个ToDo默认,有人可以帮忙,无论是使用ref是正确的选择还是其他什么,那么我错了什么我想做什么?
handleEdit() {
e.preventDefault();
.....
}
renderDisplay() {
return(
<div>
{
this.props.listArr.map((list,i) => {
return(
<div key={i} index={i} ref="newText">
<li>{list}
<div>
<button className="btn btn-primary btn-xs glyphicon glyphicon-pencil"
onClick={this.handleEdit.bind(this)}
/>
</div>
<hr/>
</li>
</div>
)})
}
</div>
);
}
renderForm() {
return(
<div>
<textarea className="form-control" defaultValue={this.refs.newText.innerText} rows="1" cols="100" style={{width: 500}}/>
</div>
)
}
render() {
if(this.state.editing) {
return this.renderForm();
}else {
return this.renderDisplay();
}
}
}
答案 0 :(得分:1)
首先,您使用old ref API。您应该使用this one,其中使用带有回调的this
将ref设置为类的实例。
<input ref={ref => {this.myInput = ref}} />
然后您只需引用this.myInput
即可访问其值。
至于你的“bug”,请记住你正在循环并覆盖ref。所以最后的引用赋值将是数组中的最后一项。
this.props.listArr.map((list,i) => {
return(
<div key={i} index={i} ref="newText">
<li>{list}
总会有1 newText
参考,它始终是数组中的最后一项。
您应该根据项id
呈现不同的引用名称,然后将项目的id
传递给renderForm
,以便它可以访问相关的引用。
话虽如此,我真的建议将todo
提取到不同的组件以及表单。在这种情况下,我没有看到使用ref的正当理由。
修改强>
作为评论的后续内容,这里有一个小例子,说明如何使用组件代替refs,以便从子级获取信息,如值等。
class Todo extends React.Component {
onClick = () => {
const { todoId, onClick } = this.props;
onClick(todoId);
}
render() {
const { value, complete } = this.props;
return (
<div
style={{ textDecoration: complete && 'line-through' }}
onClick={this.onClick}
>
{value}
</div>
);
}
}
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
todos: [
{ id: '1', value: 'to do this', complete: false },
{ id: '2', value: 'todo that', complete: true },
{ id: '3', value: 'will do it later', complete: false }]
}
}
toggleTodo = (todoId) => {
const { todos } = this.state;
const nextState = todos.map(todo => {
if (todo.id !== todoId) return todo;
return {
...todo,
complete: !todo.complete
}
});
this.setState({ todos: nextState });
}
render() {
const { todos } = this.state;
return (
<div >
{
todos.map((todo) => {
return (
<Todo
complete={todo.complete}
key={todo.id}
todoId={todo.id}
value={todo.value}
onClick={this.toggleTodo}
/>
)
})
}
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>