Raect приложение с MLabDB ( II). - Hallo sahabat Dev-Create, Pada Artikel yang anda baca kali ini dengan judul Raect приложение с MLabDB ( II)., kami telah mempersiapkan artikel ini dengan baik untuk anda baca dan ambil informasi didalamnya. mudah-mudahan isi postingan Artikel MLab, Artikel MUI, Artikel React.js, yang kami tulis ini dapat anda pahami. baiklah, selamat membaca.

Judul : Raect приложение с MLabDB ( II).
link : Raect приложение с MLabDB ( II).

Baca juga


Raect приложение с MLabDB ( II).





На этом этапе у нас есть приложение, которое не сохраняет внесенные изменения в базу данных MLab.

Давайте научим его делать это.

Внесение изменений в базу данных (checked)

Первое, что мы сделаем, это зададим в файле App.css класс, который будет добавляться к каждому таску, если у него checked: true и будет делать текст зачеркнутым.



.completed {
text-decoration: line-through;
}



Теперь применим этот класс к компоненту. Для того, чтобы это сработало мы создадим функцию, которая будет срабатывать на событие onChange, привяжем ее к this и конкретному таску, чтобы была возможность отследить изменения.

TaskItem.js


import React, { Component } from "react";
import { Checkbox } from "muicss/react";

class TaskItem extends Component {
constructor(props) {
super(props)
this.state = {
task: props.task
}
}
onChange(task, e) {
this.props.onEditState(task, e.target.checked);
}

render() {
return <div className="mui--divider-bottom">
<Checkbox
className={(this.state.task.completed) ? "completed" : ""}
onChange={this.onChange.bind(this, this.state.task)}

name={this.state.task._id.$oid}
label={this.state.task.text}
defaultChecked={this.state.task.completed}
/>
</div>;
}
}

export default TaskItem;



Так как у нас все взаимодействия с базой идут из файла App.js, то нам нужно оттуда и передавать данные в базу, поэтому поднимаемся на уровень выше - к родителю Tasks.js.

Здесь мы создадим функцию handleEditState(task, checked), которая принимает два параметра, а именно таск и отмеченный и передадим ее в компонент TaskItem.js, где мы ее написали внутри функции onChange.



import React, { Component } from 'react';
import { Panel } from 'muicss/react';
import TaskItem from './TaskItem';


class Tasks extends Component {
handleEditState(task, checked) {
this.props.onEditState(task, checked)
}

render() {
let taskItems;
if (this.props.tasks) {
taskItems = this.props.tasks.map(task => {
return (
<TaskItem
onEditState={this.handleEditState.bind(this)}
key={task._id.$oid}
task={task}
/>
)
})
}
return (
<Panel>
{taskItems}
</Panel>
);
}
}

export default Tasks;




И теперь, наконец-то создадим самое основное в родителе - App.js

Вначале мы создадим саму функцию



editState(task,checked){
console.log(task);
}


теперь передадим ее компоненту:


<Tasks
onEditState={this.editState.bind(this)}
...



И если сейчас посмотреть в консоли приложения, то в момент, когда мы отмечаем чекбокс, мы видим в консоли все данные таска:



Если в консоль вывести параметр чекед, то мы увидим следующее:



Таким образом, мы убедились, что в функцию приходят именно те данные, которые нам нужны.

Теперь наша задача внести изменения в базу.

Для этого мы воспользуемся опять axios, почти как при получении данных, но с некоторым отличием в URL, туда нам нужно передать идентификатор отмеченного бокса, чтобы внести изменения именно в нужный таск.

Обратите внимание, что в строку мы вставляем JS-код обычным сложением строк - конкатенацией.



"https://api.mlab.com/api/1/databases/react-tasks/collections/tasks/" + task._id.$oid + "?apiKey=yourAPIkey"



Метод запроса будет уже put. Передаем данные data. Создаем временную переменную let tasks , проходим циклом по всем таскам и если есть соответсвие по идентификатору, то меняем значение нужного таска completed на checked

И на основании этого изменяем состояние компонента: this.setState({ tasks: tasks });

Приведу код полностью



import React, { Component } from 'react';
import { Appbar, Container } from 'muicss/react';
import axios from 'axios';
import Tasks from './Components/Tasks';
import './App.css';

class App extends Component {
constructor() {
super()
this.state = {
tasks: []
}
}

componentWillMount() {
this.getTasks();
}

getTasks() {
axios
.request({
method: "get",
url:
"https://api.mlab.com/api/1/databases/react-tasks/collections/tasks?apiKey=yourAPIkey"
})
.then(response => {
this.setState(
{
tasks: response.data
},
() => {
console.log(this.state);
}
);
})
.catch(error => {
console.log(error);
});
}
editState(task, checked) {
axios
.request({
method: "put",
url:
"https://api.mlab.com/api/1/databases/react-tasks/collections/tasks/" + task._id.$oid + "?apiKey=yourAPIkey",
data: {
text: task.text,
completed: checked
}
}).then((response) => {
let tasks = this.state.tasks;
for (let i = 0; i < tasks.length; i++) {
if (tasks[i]._id.$oid === response.data._id.$oid) {
tasks[i].completed = checked;
}
}
this.setState({ tasks: tasks });
}).catch(error => {
console.log(error);
});
}

render() {
return (
<div className="App">
<Appbar>
<Container>
<table width="100%">
<tbody>
<tr>
<td className="mui--appbar-height">
<h3>React Tasks</h3>
</td>
</tr>
</tbody>
</table>
</Container>
</Appbar>
<br />
<Container>
<Tasks
onEditState={this.editState.bind(this)}
tasks={this.state.tasks}
/>
</Container>
</div>
);
}
}

export default App;



Теперь мы можем посмотреть в консоль и убедиться, если мы все сделали правильно, то при отметке чекбокса, у нас будет появляться зачеркнутый текст и такое же состояние будет при обновлении страницы.

Ниже на фото вы можете увидеть, что все изменения чекбокса успешно попадают в базу.



Слева - браузер, справа - база данных MLab.

Таким образом мы получили сохранение изменений при отметке чекбокса в базу данных MLab (mongodb).

Да и еще, я уже писал про сохранение ключей в безопасном месте и поэтому я вам рекомендую хранить их в отдельном файле.

Например keys/apiKeys.js в переменной:

export const apiKey = 'ВАШ_КЛЮЧ_API';

и получать их в App.js импортом -

import {apiKey} from './keys/apikeys';

Это позволит легко добавить ключи в .gitignore и они не попадут, даже случайно, в "нечистые руки".

Код на данном этапе доступен по ссылке: react-mui-mlab-abc
ci -m "Transfer of changes to the database and their preservation."


Создание формы добавления задачи.

В папке компонентов для этого создадим отдельный файл AddTask.jsВсе содержимое приведу полностью, чтобы вы могли сразу понять, что в нем нет ничего необычного или достойного отдельного объяснения.



import React, { Component } from "react";
import { Form, Input } from "muicss/react";

class AddTask extends Component {
constructor(props) {
super(props)
this.state = {
task: ''
}
}
onSubmit(e) {
this.props.onAddTask(this.state.task);
e.preventDefault();
}

onChange(e) {
this.setState({ task: e.target.value })
}
render() {
return <div className="mui--divider-bottom">
<Form onSubmit={this.onSubmit.bind(this)}>
<Input hint="Add Task" onChange={this.onChange.bind(this)} />
</Form>
</div>;
}
}

export default AddTask;



Поля Form и Input из библиотеки MUI.

На поле ввода повесили событие на изменение его содержимого. В функции onChange сразу сохраняем изменения в стейт.

Кнопкой запустим функцию добавления задачи - onAddTask, куда и передадим значение стейта.

Функцию получим в props, поэтому мы ее создадим позже в родителе - App.js из которого и будем взаимодействовать с базой данных.

Теперь идем в файл App.js и импортируем в него вновь созданный компонент:

import AddTask from './Components/AddTask';

Выведем его на страницу сразу после Контейнера. Передадим ему как свойство функцию addTask и создадим ее сразу над render(). Пока что выведем в нее значение переменной text:



import React, { Component } from 'react';
import { Appbar, Container, Button } from 'muicss/react';
import axios from 'axios';
import Tasks from './Components/Tasks';
import AddTask from './Components/AddTask';
import './App.css';
import { apiKey } from './keys/apikeys';

class App extends Component {
constructor() {
super()
this.state = {
tasks: []
}
}

componentWillMount() {
this.getTasks();
}

getTasks() {
axios
.request({
method: "get",
url:
"https://api.mlab.com/api/1/databases/react-tasks/collections/tasks?apiKey=" + apiKey
})
.then(response => {
this.setState(
{
tasks: response.data
},
() => {
console.log(this.state);
}
);
})
.catch(error => {
console.log(error);
});
}
editState(task, checked) {
axios
.request({
method: "put",
url:
"https://api.mlab.com/api/1/databases/react-tasks/collections/tasks/" + task._id.$oid + "?apiKey=" + apiKey,
data: {
text: task.text,
completed: checked
}
}).then((response) => {
let tasks = this.state.tasks;
for (let i = 0; i < tasks.length; i++) {
if (tasks[i]._id.$oid === response.data._id.$oid) {
tasks[i].completed = checked;
}
}
this.setState({ tasks: tasks });
}).catch(error => {
console.log(error);
});
}

addTask(text) {
console.log(text);
}


render() {
return (
<div className="App">
<Appbar>
<Container>
<table width="100%">
<tbody>
<tr>
<td className="mui--appbar-height">
<h3>React Tasks</h3>
</td>
</tr>
</tbody>
</table>
</Container>
</Appbar>
<br />
<Container>
<AddTask onAddTask={this.addTask.bind(this)} />
<Tasks
onEditState={this.editState.bind(this)}
tasks={this.state.tasks}
/>
</Container>
</div>
);
}
}

export default App;



Если посмотреть на то, что получилось в браузере, то мы можем ввести какой-либо текст, нажать Enter и в консоли увидим это же значение:



Запрос на добавление данных в базу.

Все что нам нужно это написать функцию, которая будет взаимодействовать с базой при помощи axios

Пишем простой запрос. Указываем метод post, немного изменяем URL (это можно посмотреть в данных базы. Об этом рассказывал в первой части.).

Далее пишем данные, которые будем передавать.

Во временную переменную сохранили то что было в стейте до этого. Добавили методом push новые данные.

В данных completed: false, потому что мы предполагаем, что изначально задание не сделано.

При успешном выполнении вносим изменения в стейт.

В случае ошибки - поймали ее и вывели в консоль. Это если коротко...



addTask(text) {
axios
.request({
method: "post",
url:
"https://api.mlab.com/api/1/databases/react-tasks/collections/tasks?apiKey=" + apiKey,
data: {
text: text,
completed: false
}
}).then((response) => {
let tasks = this.state.tasks;
tasks.push({
_id: response.data._id,
text: text,
completed: false
})
this.setState({ tasks: tasks });
}).catch(error => {
console.log(error);
});
}



Посмотрим в браузер:



Вводим какой-либо текст. Нажимаем Enter и видим обновление данных на странице без перезагрузки и, соответственно данных в базе.

Для того, чтобы в этом убедиться, можно просто перезагрузить страницу и мы получим те же "новые" данные.

Код на данном этапе доступен по ссылке: react-mui-mlab-abc
ci -m "Added task to DataBase"


Добавление кнопки удаления выполненных заданий.

Начнем с тобой, что добавим саму кнопку в компонент.

В импорт из MUI добавим импорт кнопки:

import { Appbar, Container, Button } from 'muicss/react';

И прямо над закрывающим тегом контейнера, выведем саму кнопку удаления. Добавим ей красный цвет.

На клик повесим функцию, которую сейчас же и создадим.


<Container>
<AddTask onAddTask={this.addTask.bind(this)} />
<Tasks
onEditState={this.editState.bind(this)}
tasks={this.state.tasks}
/>
<Button color="danger" onClick={this.clearTasks.bind(this)} >
Clear Tasks
</Button>

</Container>


Посмотрим в браузере:



Сделаем кнопку работающей.

Функция clearTasks

Во временную переменную tasks, получим все задания из состояния.

Для удобства, кол-во заданий вынесем в отдельную переменную - i

Пройдем по всем заданиям циклом while от большего к меньшему и если оно выполнено (completed), то методом splice уберем его из массива.

Здесь же внесем изменения в базу методом delete

Для работы с базой данных MongoDB нам нужен доступ не просто по идентификатору, а по _id.$oid

Ответ - стандартное подтверждение удаления и ошибку ловим в консоль.



clearTasks() {
let tasks = this.state.tasks;
let i = tasks.length;

while (i--) {
if (tasks[i].completed === true) {
let id = tasks[i]._id.$oid;
tasks.splice(i, 1);
axios.request({
method: 'delete',
url: "https://api.mlab.com/api/1/databases/react-tasks/collections/tasks/" + id + "?apiKey=" + apiKey,
}).then(response => {

}).catch((error) => {
console.log(error)
})
}
}
this.setState({ tasks: tasks })
}



Теперь вы сможете не только добавить новые задачи, но и отметить выполненные, и при необходимости их удалить.

Проверяем:



Код на данном этапе доступен по ссылке: react-mui-mlab-abc
ci -m "Delete completed tasks from DataBase"


Можно еще порефакторить код. Сделать автоматическую очистку поля при добавлении задачи и многое другое. Можно вообще, переписать код в виде функциональных компонентов используя современные возможности хуки и пр.

К примеру, для очистки поля ввода можно сделать так.
  1. К самой форме ввода добавить id - компонент <Form id="form"/ >
  2. В функцию отправки onSubmit, добавить строку очистки всей формы: document.getElementById("form").reset();

  3. onSubmit(e){
    this.props.onAddTask(this.state.task);
    e.preventDefault();
    document.getElementById("form").reset();
    }



Данный проект в постах, можно рассматривать, скорее как учебный. Здесь все понятно. Я специально не пытался сокращать код, именно для его понимания и простоты.

Спасибо тем. кто дочитал до конца и

...Happy Coding!



                                                                                                                                                             

Телеграм канал - Full Stack JavaScript Developer


Demikianlah Artikel Raect приложение с MLabDB ( II).

Sekianlah artikel Raect приложение с MLabDB ( II). kali ini, mudah-mudahan bisa memberi manfaat untuk anda semua. baiklah, sampai jumpa di postingan artikel lainnya.

Anda sekarang membaca artikel Raect приложение с MLabDB ( II). dengan alamat link https://dev-create.blogspot.com/2019/03/raect-mlabdb-ii.html