Простое пошаговое руководство по данным, дизайну и рендерингу компонентов

Создавая свой личный сайт, я хотел чего-то более личного, чем простой текст. Я решил собрать чат-бота, чтобы рассказать о различных проектах, на которые я ссылался на своем веб-сайте (Figma, Medium, Github, Instagram и т. Д.).

Вы можете посмотреть, как я использовал приложение, на моем сайте ниже или по демо-ссылке!

Ресурсы

Я расскажу, как я собрал чат-бота, за пару часов ниже, следуя этим этапам:

  • Дизайн
  • Поток пользователей
  • Структура данных
  • Реагировать на рендеринг

Дизайн

Мы начинаем с дизайна, потому что большинство из нас знакомы с некоторыми формами чата.

Обозначьте поток

Говорят два человека - вы и человек, с которым разговариваете. Итак, типичный дизайн выглядит примерно так:

Давайте добавим цвета.

Большинство приложений для чата придерживаются одного цвета.

Чтобы убедиться, что у нас хороший пользовательский дизайн, нам нужно следующее:

  • Один основной цвет
  • Остальное остается монохромным (черный, белый или серый).
  • Между цветом и цветом выбранного текста должен быть высокий контраст. Это облегчает чтение текста.
  • Будьте проще - содержание разговора важнее внешнего вида!

Добавьте стили

  • Bubble

Это будет один и тот же код для ответа, вопроса и пользовательских ответов.

border: none; to override the button default border.
border-radius: 2em. To give it round edges.
padding: 1em. To make it bubble-like.
max-width: fit-content. This makes the bubble to fit the text.
margin: none; We’ll add margin from the parent container.
box-shadow: 0px 2px 10px rgba(162, 155, 254, 0.25); to add a glow around the bubble.

  • questionBubble
background: WhiteSmoke; // this is purple
color: #a29bfe;
  • responseBubble (.s.bubble)

Когда они будут отрисованы, они будут принадлежать к классу s bubble.

Мы хотим сделать цвета противоположными questionBubble.

background: #a29bfe;
color: white;

К выбранному пузырю будет добавлен класс selected. Класс будет selected s bubble.

Выбранный пузырь имеет более темный фон.

background-color: #6c5ce7;

Когда кнопки наведены, они будут иметь тень прямоугольника.

box-shadow: 0px 0px 15px 0px #6c5ce7b0;
  • Custom Response Bubble

Это будет то же самое, что и стили пузырей вопроса.

  • questionContainer

Это выровняет текст по левому краю контейнера, и контейнер должен охватывать всю ширину родительского элемента.

text-align: -webkit-left;
  • responseContainer

Это выровняет текст по правому краю контейнера, и контейнер должен охватывать всю ширину родительского элемента.

text-align: -webkit-right;
  • chatContainer

В зависимости от каких-либо стилей, которые могут быть унаследованы в этом div, вы можете изменить стили здесь. У меня не было ничего смешного, поэтому я не добавил сюда никаких стилей.

Но вы можете установить ширину 80vw и убедиться, что высота динамична с содержимым!

Все стили можно увидеть здесь:

Стили для чат-бота от Нивааз

Поток пользователей

Чтобы сделать это просто:

  • Задаем первый вопрос.
  • Пользователь нажимает на один из ранее заданных нами ответов.
  • Мы отвечаем индивидуальным ответом на то, что выбрал пользователь.

Данные

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

Мои файлы JSON имеют следующую структуру и попадают в мою папку «данные».

Состав

Массив записей для каждого вопроса и ответа. Каждая запись массива содержит:

  • строка вопроса.
  • массив строк ответов.
  • customResponse строка.

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

Вот два моих ответа в файле JSON:

Файл JSON для данных разговора.

Код

Вот компоненты, которые мы будем делать:

  • Convo (родительский компонент).
  • Вопрос (отображает вопросы).
  • Ответ (отображает кнопки ответа).
  • Пользовательский ответ (отображает ответ клиента относительно нажатой кнопки ответа).

Я собираюсь использовать create-response-app, чтобы запустить новое приложение React. Затем я собираюсь добавить папку компонентов и папки для каждого из компонентов, а также файл JavaScript и CSS. Обязательно импортируйте React для каждого компонента:

import React from "react"

Каждый файл JavaScript будет выглядеть одинаково. Вот пример компонента customResponse:

export const CustomResponse = (props) => {
return (<p> {props.customResponse} </p>)
}

Конво

Convo - это родительский компонент, который будет отображать данные и отображать компоненты Question, Response и CustomResponse.

Импорт

Сначала импортируйте файл JSON из любого места, где хранятся ваши данные, используя следующий код:

import convo from "../data/convo.json";
import React from "react"
import { Question } from "../Question/Question";
import { Response } from "../Response/Response";
import { CustomResponse } from "../CustomResponse/CustomResponse";
import convo from '../../data/convo.json';
import "./convo.css";

Затем мы хотим импортировать другие компоненты и файл CSS.

Сделайте Convo компонентом класса

Мы собираемся изменить определение Convo на компонент React. Мы также собираемся добавить состояние. В государстве будут находиться:

  • currentQuestion: номер
  • answersArray: число []
export class Convo extends React.Component {
state = {
currentQuestion: 0,
answers: []
};
render () {
return (<p> Convo Component </p>)
  }
}

RenderConversation функция

Эта функция отобразит данные разговора, а затем отобразит дочерние компоненты Question, Response и Custom Response. Каждому дочернему компоненту также передается опора для своего имени.

Функция renderConversation

Вопрос

Question нужны дополнительные реквизиты. Мы собираемся добавить их в объявление в Convo.js. Теперь у вопроса будут следующие реквизиты:

<Question
   question={key.question}
   questionIndex={index}
   currentQuestion={this.state.currentQuestion}
 />

Теперь давайте добавим код для отображения вопросов в соответствии с состоянием currentQuestion in. Вопрос должен отображаться только тогда, когда questionIndex меньше или равно currentQuestion.

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

Ответ

Ответу также потребуются дополнительные реквизиты, поэтому мы собираемся обновить Convo.js. Обратите внимание, что ключ данных конвоя называется «ответы», а не «ответ».

<Response
responses={key.responses}
currentQuestion={this.state.currentQuestion}
answers={this.state.answers}
questionIndex={index}
/>

renderBubble

Чтобы упростить чтение кода и сделать его короче, я добавил функцию рендеринга кнопки ответа, renderBubble. Это принимает значение параметра, имя, ключ и выбранный.

handleResponseClick

Это функция, которая срабатывает при нажатии ответа. Это будет объявлено в файле Convo.js и обновит как currentQuestion, так и ответы в состоянии.

Функция будет передана в компонент Response через props.

Итак, Response в Convo.js теперь выглядит так (это будет связано с onClick в response кнопках):

<Response
responses={key.responses}
currentQuestion={this.state.currentQuestion}
answers={this.state.answers}
questionIndex={index}
handleResponseClick={this.onClickResponse}
/>

onClickResponse (в Convo.js)

onClickResponse = (e) => {
const questionIndex = Number(e.target.name);
const answerResult = Number(e.target.value);
let ans = this.state.answers;
ans[questionIndex] = answerResult;
this.setState({
currentQuestion: questionIndex + 1,
answers: ans
},
console.log( "state", this.state.answers, this.state.currentQuestion));
}

Функциональность

responses не является массивом, поэтому мы будем отображать его.

У нас есть три случая, когда ответы отображаются или нет:

  • Когда questionIndex меньше currentQuestion, тогда будет выбранный и невыбранный ответ.
  • Когда questionIndex равно currentIndex, отображаются оба ответа, но ни один из них не выбран.
  • Если questionIndex больше, чем currentQuestion, ничего не должно отображаться.

Для выбранной кнопки я только что добавил выбранный класс. Выбранная кнопка отображается в зависимости от значения в массиве ответов, т.е. answers[questionIndex].

CustomResponse

Последний компонент!

Добавить реквизит в Convo.js

<CustomResponse
questionIndex={index}
currentQuestion={this.state.currentQuestion}
answers={this.state.answers}
customResponse={key.customResponse}
/>

Функциональность

  • Пользовательский ответ должен отображаться только для questionIndexes меньше currentQuestion.
  • Пользовательский ответ будет отображаться только в том случае, если выбранный ответ был равен 0 (так как я написал свои кнопки ответа и пользовательские ответы).

Таким образом, код будет выглядеть примерно так:

Наконец, наш код должен заработать! Вы можете увидеть живую демонстрацию чат-бота здесь и весь код ниже. Здесь же можно найти ссылку на репозиторий GitHub.