Веб-приложение или сайт, который загружает только одну страницу и все последующие запросы обрабатываются без полной перезагрузки страницы.
Приложение, которое может работать как на стороне сервера, так и на стороне клиента.
import React from 'react';
function Form() {
return (
<div className="form">
<input placeholder="Ключ заметки" />
<textarea placeholder="Текст заметки" />
<button>Добавить новую заметку</button>
</div>
);
}
import React from 'react';
class Form extends React.Component {
render() {
return (
<div className="form">
<input placeholder="Ключ заметки" />
<textarea placeholder="Текст заметки" />
<button>Добавить новую заметку</button>
</div>
);
}
}
<div id="root"></div>
import React from 'react';
import ReactDOM from 'react-dom';
import Form from './Form';
ReactDOM.render(<Form />, document.getElementById('root'));
<div>
<img className="logo" src="./images/logo.svg" />
<h1 className="title">Список заметок</h1>
</div>
React.createElement(
"div",
null,
React.createElement("img", { className: "logo", src: "./images/logo.svg" }),
React.createElement("h1", { className: "title" }, "Список заметок")
);
<input class="name" tabindex="2" />
<input className="name" tabIndex="2" />
<div>
<span>Введите ваше имя:</span><br>
<input type="text">
</div>
<div>
<span>Введите ваше имя:</span><br />
<input type="text" />
</div>
|
|
|
|
function MyComponent() {
return (
<p>Первый абзац</p>
<p>Второй абзац</p>
);
}
function MyComponent() {
return (
<div>
<p>Первый абзац</p>
<p>Второй абзац</p>
</div>
);
}
function MyComponent() {
return (
<React.Fragment>
<p>Первый абзац</p>
<p>Второй абзац</p>
</React.Fragment>
);
}
function MyComponent() {
return (
<>
<p>Первый абзац</p>
<p>Второй абзац</p>
</>
);
}
const user = { name: 'Наташа' };
function Greeting() {
return <div>Привет, {user.name}</div>;
}
const someHtml = '<strong>Наташа</strong>';
function Greeting() {
return <div>Привет, {someHtml}</div>;
}
const someHtml = '<strong>Наташа</strong>';
function Greeting() {
return (
<div dangerouslySetInnerHTML={{ __html: someHtml }} />
);
}
import Form from './Form';
import Notes from './Notes';
function NotesApp() {
return (
<div className="notes-app">
<Notes />
<Form />
</div>
);
}
function SomeComponent() {
return (
<OtherComponent
text="Text"
id={2}
data={[1, 3, 4]}
/>
);
}
function Notes() {
return (
<div className="notes">
<Note name="Books" text="Books to read" />
<Note name="Music" text="Music to listen" />
<Note name="Films" text="Films to watch" />
</div>
);
}
function Note({ name, text }) {
return (
<div className="note">
<h1>{name}</h1>
<p>{text}</p>
</div>
);
}
export default class Note extends React.Component {
render() {
const { name, text } = this.props;
return (
<div className="note">
<h1>{name}</h1>
<p>{text}</p>
</div>
);
}
}
import PropTypes from 'prop-types';
function Note({ name, text }) {
return ...
}
Note.propTypes = {
name: PropTypes.string,
text: PropTypes.string.isRequired
};
Note.defaultProps = {
name: 'Note name'
};
import PropTypes from 'prop-types';
export default class Note extends React.Component {
static propTypes = {
name: ,
text: PropTypes.string.isRequired
}
static defaultProps = { name: 'Note name' }
render() {
const { name, text } = this.props;
return ...
}
}
import React from 'react';
const ThemeContext = React.createContext('light');
export default ThemeContext;
import ThemeContext from './ThemeContext.js';
function NotesApp() {
return (
<ThemeContext.Provider value="dark">
...
</ThemeContext.Provider>
);
}
import ThemeContext from './ThemeContext.js';
function Note() {
return (
<ThemeContext.Consumer>
{theme => {
return <div className={theme}>...</div>;
}}
</ThemeContext.Consumer>
);
}
function Notes() {
return (
<div className="notes">
<Note name="Books">
<span>Books to read</span>
<button>Like!</button>
</Note>
</div>
);
}
function Note({ name, children }) {
return (
<div className="note">
<h1>{name}</h1>
<p>{children}</p>
</div>
);
}
export default class Note extends React.Component {
constructor(props) {
super(props);
this.state = { viewType: 'short' };
this.viewFull = () => this.setState({ viewType: 'full' })
}
render() {
...
}
}
export default class Note extends React.Component {
state = { viewType: 'short' }
viewFull = () => this.setState({ viewType: 'full' })
render() {
const { viewType } = this.state;
return (
<div className="note">
<h1>Название заметки</h1>
{viewType === 'short'
? (
<React.Fragment>
<p>Краткое содержание</p>
<button onClick={this.viewFull}>Читать подробнее</button>
</React.Fragment>
) : <p>Полный текст</p>
}
</div>
);
}
}
export default class Note extends React.Component {
state = { viewType: 'short' }
viewFull = () => this.setState({ viewType: 'full' })
render() {
const { viewType } = this.state;
return (
<div className="note">
<h1>Название заметки</h1>
{viewType === 'short'
? (
<React.Fragment>
<p>Краткое содержание</p>
<button onClick={this.viewFull}>Читать подробнее</button>
</React.Fragment>
) : <p>Полный текст</p>
}
</div>
);
}
}
export default class Note extends React.Component {
state = { viewType: 'short' }
viewFull = () => this.setState({ viewType: 'full' })
render() {
const { viewType } = this.state;
return (
<div className="note">
<h1>Название заметки</h1>
{viewType === 'short'
? (
<React.Fragment>
<p>Краткое содержание</p>
<button onClick={this.viewFull}>Читать подробнее</button>
</React.Fragment>
) : <p>Полный текст</p>
}
</div>
);
}
}
export default class Note extends React.Component {
state = { viewType: 'short' }
viewFull = () => this.setState({ viewType: 'full' })
render() {
const { viewType } = this.state;
return (
<div className="note">
<h1>Название заметки</h1>
{viewType === 'short'
? (
<React.Fragment>
<p>Краткое содержание</p>
<button onClick={this.viewFull}>Читать подробнее</button>
</React.Fragment>
) : <p>Полный текст</p>
}
</div>
);
}
}
Хуки — это функции, с помощью которых вы можете «подцепиться» к состоянию и методам жизненного цикла React из функциональных компонентов.
import React, { useState } from 'react';
function Example() {
// Объявление переменной состояния, которую мы назовём "count"
const [count, setCount] = useState(0);
return (
<div>
<p>Вы нажали {count} раз</p>
<button onClick={() => setCount(count + 1)}>
Нажми на меня
</button>
</div>
);
}
import React, { useState } from 'react';
function ExampleWithManyStates() {
// Объявляем несколько переменных состояния
const [age, setAge] = useState(42);
const [fruit, setFruit] = useState('банан');
const [todos, setTodos] = useState([{ text: 'Изучить хуки' }]);
// ...
}
import React, { useEffect, useState } from 'react';
function Example() {
const [count, setCount] = useState(0);
// Аналогично componentDidMount и componentDidUpdate:
useEffect(() => { document.title = `Вы нажали ${count} раз`; });
return (
<div>
<p>Вы нажали {count} раз</p>
<button onClick={() => setCount(count + 1)}>
Нажми на меня
</button>
</div>
);
}
function NotesList({ notes }) {
return notes.map(note => (
<Note name={note.name} text={note.text} />
));
}
Each child in an array or iterator should have a unique "key" prop.
Check the render method of NotesList. See https://fb.me/react-warning-keys for more information.
function NotesList({ notes }) {
return notes.map(note => (
<Note key={note.id} name={note.name} text={note.text} />
));
}
DOM управляет текущим состоянием компонента
class Form extends React.Component {
inputRef = React.createRef();
handleSubmit = () => this.makeSomeApiRequest(
this.inputRef.current.value
)
render() {
return (
<form onSubmit={this.handleSubmit}>
<input ref={this.inputRef} />
<button>Отправить</button>
</form>
);
}
}
class Form extends React.Component {
inputRef = React.createRef();
handleSubmit = () => this.makeSomeApiRequest(
this.inputRef.current.value
)
render() {
return (
<form onSubmit={this.handleSubmit}>
<input ref={this.inputRef} />
<button>Отправить</button>
</form>
);
}
}
class Form extends React.Component {
inputRef = React.createRef();
handleSubmit = () => this.makeSomeApiRequest(
this.inputRef.current.value
)
render() {
return (
<form onSubmit={this.handleSubmit}>
<input ref={this.inputRef} />
<button>Отправить</button>
</form>
);
}
}
React управляет текущим состоянием компонента
class Form extends React.Component {
state = { value: '' }
handleSubmit = () => this.makeSomeApiRequest(this.state.value)
handleChange = event => this.setState({
value: event.target.value
})
render() {
return (
<div>
<input value={this.state.value} onChange={this.handleChange} />
<button onClick={this.handleSubmit}>
Отправить
<button>
</div>
);
}
}
class Form extends React.Component {
state = { value: '' }
handleSubmit = () => this.makeSomeApiRequest(this.state.value)
handleChange = event => this.setState({
value: event.target.value
})
render() {
return (
<div>
<input value={this.state.value} onChange={this.handleChange} />
<button onClick={this.handleSubmit}>
Отправить
<button>
</div>
);
}
}
class Form extends React.Component {
state = { value: '' }
handleSubmit = () => this.makeSomeApiRequest(this.state.value)
handleChange = event => this.setState({
value: event.target.value
})
render() {
return (
<div>
<input value={this.state.value} onChange={this.handleChange} />
<button onClick={this.handleSubmit}>
Отправить
<button>
</div>
);
}
}
$ npm i webpack webpack-cli babel-loader babel-preset-react
// webpack.config.js
const path = require('path');
module.exports = {
entry: './index.js',
output: {
path: path.join(__dirname, './build')
},
module: {
rules: [{
test: /\.js$/,
loader: 'babel-loader',
options: {
presets: ['react']
}
}]
}
};
$ webpack --config webpack.config.js
$ npx create-react-app notes-app
$ cd notes-app
$ npm start
Compiled successfully!
You can now view notes-app in the browser.
Local: http://localhost:3000/
Note that the development build is not optimized.
To create a production build, use yarn build.
notes-app
├── README.md
├── node_modules
├── package.json
├── .gitignore
├── public
│ ├── favicon.ico
│ ├── index.html
│ └── manifest.json
└── src
├── App.css
├── App.js
├── App.test.js
├── index.css
├── index.js
├── logo.svg
└── registerServiceWorker.js
notes-app
├── README.md
├── node_modules
├── package.json
├── .gitignore
├── public
│ ├── favicon.ico
│ ├── index.html
│ └── manifest.json
└── src
├── App.css
├── App.js
├── App.test.js
├── index.css
├── index.js
├── logo.svg
└── registerServiceWorker.js
$ npx create-next-app notes-app
$ cd notes-app
$ npm run dev
[ ready ] compiled successfully - ready on http://localhost:3000
const { parse } = require('url');
const next = require('next');
const server = require('express')();
const app = next({ dev: process.env.NODE_ENV !== 'production' });
const render = pageName => (req, res) => app.render(req, res, `/${pageName}`);
const handleRequest = (req, res) =>
app.getRequestHandler()(req, res, parse(req.url, true));
app.prepare().then(() => {
server
.get('/notes', render('index'))
.get('/notes/:note', render('note'))
.get('*', handleRequest)
.listen(3000, () => console.log('Listening on http://localhost:3000'));
});