Пытаюсь воплотить вот это приложение http://todomvc.com/examples/react/#/ Имею два компонента, NoteList где имеется сам input и откуда должны по идее создаваться записи, и сама запись Note. Получается в функции onBtnClickHandler() я пытаюсь возвратить статью , таким образом создать ее , но ничего не происходит. В чем проблема?
class NoteList extends Component {
constructor(props){
super(props)
this.state={
value: ''
}
this.handleChange = this.handleChange.bind(this);
this.onBtnClickHandler = this.onBtnClickHandler.bind(this);
}
render() {
return (
<div className="NodeList_div">
<button onClick={this.onBtnClickHandler}>X</button>
<input type="text" onChange={this.handleChange} value={this.state.value}/>
<div className="nodelist_note"></div>
<div className="nodelist_footer">
2 items left
<button>X</button>
<button>X</button>
<button>X</button>
</div>
</div>
)
}
handleChange(event) {
this.setState({value: event.target.value});
console.log(this.state.value);
}
onBtnClickHandler() {
return (<div>
<Note />
</div>)
}
}
export default NoteList
Думаю, стоит разобраться с кодом и его поведением. Начнем с метода обработки клика:
onBtnClickHandler() {
return (
<div>
<Note />
</div>
);
}
Метод возвращает элемент Note
обернутый в div
тэг. Ничего сложного, на первый взгляд. Но куда возвращается этот элемент? Правильно - никуда.
Значит нужно организовать хранилище. Напрашивается сразу же state
компонента в качестве хранилища, так и поступим, будем хранить там. Так как в примере для создания Note
компонента ничего не нужно (я имею в виду props
), то достаточно хранить просто цифру с количеством записей, но мы пойдем дальше и будем хранить массив, в массиве будут ключи. Перепишем конструктор:
constructor(props) {
super(props);
this.state = {
value: '',
notes: [], // в начале будет пустой массив
}
this.handleChange = this.handleChange.bind(this);
this.onBtnClickHandler = this.onBtnClickHandler.bind(this);
}
Следующим на очереди будет метод рендеринга компонента, так как у нас появилась коллекция неких элементов, значит можно использовать метод map
для прохода по массиму и отрисовке отдельных компонент.
render() {
return (
<div className="NodeList_div">
<button onClick={this.onBtnClickHandler}>X</button>
<input type="text" onChange={this.handleChange} value={this.state.value}/>
<div className="nodelist_note">
{this.state.notes.map((note) => { return <Note key={note} />; })}
</div>
<div className="nodelist_footer">
2 items left
<button>X</button>
<button>X</button>
<button>X</button>
</div>
</div>
);
}
Здесь мы добавили простую конструкцию прохода по массиву и возвращения новой коллекции:
{this.state.notes.map((note) => { return <Note key={note} />; })}
Обратите внимание на добавленное свойство key
- если его не добавить, то React это не понравится и получите ошибки в консоли из-за того, что отрисовываете список значений и у них нет уникального поля key
. Об этом можно почитать тут: Lists and Keys. Теперь можно переписать обработчик клика на кнопку (это всего лишь пример):
onBtnClickHandler() {
const oldNotes = this.state.notes; // получить массив из state
const element = oldNotes.length; // вычислим длину массива
oldNotes.push(++element) // добавим в массив новое значение
this.setState({ notes: oldNotes }); // запишем новое значение в state
}
Вызов метода setState
и изменение значения в state
вызовет ререндеринг компонента, то есть перерисовку на форме, это в свою очередь обновит список выводимых значений в div
блоке nodelist_note
.
Виртуальный выделенный сервер (VDS) становится отличным выбором
Как сделать что бы сравнивало 1 с 1, 2 с 2 буквой, а не 1 со всеми 2 строки
Я добавляю триггеры в свою БД, далее пытаюсь выполнить запрос, запрос выполняется, а триггер нетПривожу в пример один из созданных триггеров...