Из заголовка поста вы понимаете, что я не только собираюсь объяснить, как реализовать традиционный TODO-List с помощью React, но также покажу вам, как я применяю Emotion-js для этого. мини-проект.

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

После этого мы напишем простой TODO-List. Я решил просто поместить приведенный ниже код, потому что основной смысл сообщения заключается в использовании библиотеки Emotion для стилизации извлеченных компонентов.

Простой TODO-список с React:

// TodoList.js
import React from 'react';
export const TodoList = (props) => {
    return(
        <ul>
            {props.todoItems.map((todo, index) =>
                <li key={index}>{todo}</li>
            )}
        </ul>
    );
};

а также

// App.js
import React, {Component} from 'react';
import './App.css';
import {TodoList} from './TodoList';
class App extends Component {
    constructor() {
        super();
this.state = {
            inputValue: '',
            todoItems: []
        };
this.onChangeInputValue = this.onChangeInputValue.bind(this);
        this.onSubmitInputValue = this.onSubmitInputValue.bind(this);
    }
onChangeInputValue(event) {
        this.setState({
            inputValue: event.target.value
        });
    }
onSubmitInputValue(event) {
        event.preventDefault();
        this.setState({
            inputValue: '',
            todoItems: [...this.state.todoItems, this.state.inputValue]
        });
    }
render() {
        return (
            <div>
                <form onSubmit={this.onSubmitInputValue}>
                    <input type="text"
                           value={this.state.inputValue}
                           onChange={this.onChangeInputValue}/>
                    <button>Create</button>
                </form>
                <TodoList todoItems={this.state.todoItems}/>
            </div>
        );
    }
}
export default App;

Я хотел бы иметь компонент со стилем Emotion, который принимает реквизиты, которые в конечном итоге управляют стилем. Более того, любое выражение или интерполяция может быть функцией, а классы CSS - это то, что мы генерируем, когда используем модули SCSS / CSS. Это убедительный шаблон, который можно использовать для создания повторно используемых стилей в любом проекте.

Итак, следующим шагом будет установка наиболее полезных пакетов Emotion:

npm install --save emotion react-emotion babel-plugin-emotion

Вместо того, чтобы стилизовать элементы DOM с помощью CSS, я создал Стилизованные компоненты, чтобы затем я мог вызывать его с помощью литерала шаблона для стилей строк везде в проекте, который мне нужен.

Поскольку я предпочитаю планирование и стилизацию из контейнеров и оболочек (особенно, если я использую для этого flexbox), я начал с извлечения, стилизации и использования компонентов ‹Container /› и ‹Wrapper /›.

// App.js
...
// importing styled method 
import styled from 'react-emotion';
...
// declaring a new component
const Container = styled('div')`
    display: flex;
    overflow: hidden;
    justify-content: center;
    height: 100vh;
    align-items: center;
    font-family: 'Source Sans Pro', sans-serif;
    flex-direction: column;
    box-shadow: 0 0 5px rgba(25, 25, 25, 0.25);
`;
const Wrapper = styled('div')`
    display: flex;
    flex-direction: column;
    background: white;
    border-radius: 20px;
`;
class App extends Component {
 ...
 render() {
        return (
 // applying components
            <Container>
                <Wrapper>
                     <form onSubmit={this.onSubmitInputValue}>
   ...
                </Wrapper>
            </Container>
        );
    }
}
export default App;

Затем я создал компоненты: ‹CreateTodoForm /›, ‹CreateTodoInput /› и ‹CreateTodoButton /› для стилизации формы, разделил их на js-файлы и импортировал в App.js.

// CreateTodoForm.js
import React from 'react';
import styled from 'react-emotion';
export const CreateTodoForm = styled('form')`
    width: 400px;
    padding: 1rem;
    display: flex;
    border-radius: 20px;
`;

а также

// CreateTodoInput.js
import React from 'react';
import styled from 'react-emotion';
export const CreateTodoInput = styled('input')`
    width: 100%;
    font-size: 14px;
    margin: 0 0.5rem;
    border-radius: 2rem;
    padding: .75em 1.5rem;
    background: none;
    border: #e3e3e3 1px solid;
    transition: border 250ms ease-out;
    &:focus {
        border: #4fc08d 1px solid;
        outline: none;
    }
`;

а также

// CreateTodoButton.js
import React from 'react';
import styled from 'react-emotion';
export const CreateTodoButton = styled('button')`
    font-size: 14px;
    margin: 0 0.5em;
    border-radius: 2em;
    padding: 0.75em 1.5em;
    cursor: pointer;
    background: none;
    border: 1px solid #4fc08d;
    letter-spacing: 1px;
    font-family: "Source Sans Pro", sans-serif;
    color: #4fc08d;
    transition: 250ms ease-out;
    &:hover, &:focus {
        color: #fff;
        background: #4fc08d;
        outline: none;
    }
`;

тогда

// App.js
import React, {Component} from 'react';
import styled from 'react-emotion';
import './App.css';
import {TodoList} from './TodoList';
// importing form-components
import {CreateTodoInput} from './components/CreateTodoInput';
import {CreateTodoButton} from './components/CreateTodoButton';
import {CreateTodoForm} from './components/CreateTodoForm';
const Container = styled('div')`
    display: flex;
    overflow: hidden;
    justify-content: center;
    height: 100vh;
    align-items: center;
    font-family: 'Source Sans Pro', sans-serif;
    flex-direction: column;
    box-shadow: 0 0 5px rgba(25, 25, 25, 0.25);
`;
const Wrapper = styled('div')`
    display: flex;
    flex-direction: column;
    background: white;
    border-radius: 20px;
`;
class App extends Component {
    constructor() {
        super();
this.state = {
            inputValue: '',
            todoItems: []
        };
this.onChangeInputValue = this.onChangeInputValue.bind(this);
        this.onSubmitInputValue = this.onSubmitInputValue.bind(this);
    }
onChangeInputValue(event) {
        this.setState({
            inputValue: event.target.value
        });
    }
onSubmitInputValue(event) {
        event.preventDefault();
        this.setState({
            inputValue: '',
            todoItems: [...this.state.todoItems, this.state.inputValue]
        });
    }
render() {
        return (
            <Container>
                <Wrapper>
   // applying components to render them
                    <CreateTodoForm onSubmit={this.onSubmitInputValue}>
                        <CreateTodoInput type="text"
                               value={this.state.inputValue}
                               onChange={this.onChangeInputValue}/>
                        <CreateTodoButton>Create</CreateTodoButton>
                    </CreateTodoForm>
                    <TodoList todoItems={this.state.todoItems}/>
                </Wrapper>
            </Container>
        );
    }
}
export default App;

Вот окончательный результат:

На сегодня все. Надеюсь, вам понравится мое небольшое объяснение! Спасибо за чтение! 👏