React

  1. Где учить
  2. Мысли от обучения
  3. Установка на линукс для бэк
  4. Как я понял
  5. Как работает jsx
  6. Как добавить клик
  7. Input
  8. Пример с состоянием
  9. Большой пример с передачей функций
React

Где учить

Не любитель этих библиотек, но если за них платят.. Основы Основы (объясняют лучше) web Учебник Документация Next JS Вакансии

Мысли от обучения

Блин, напридумывали свои правила и ограничения.. На обычном js можно создать всё тоже самое.. Непривычным пока что избавление от кавычек.. Чем больше узнаю реакт, тем больше за VanillaJS.. Я ближе к тому, что знание алгоритмов и умение их применить, более ценное, чем знание библиотек.. Солидарен с этим челом

Установка на линукс для бэк

sudo apt update curl -sL https://deb.nodesource.com/setup_16.x | sudo bash - sudo apt-get install -y nodejs npm install -g npm@6 npx create-react-app my-app // Оптимизировать npm run build // Запуск npm install pm2 -g pm2 start npm -- start pm2 logs pm2 ps pm2 stop 0 // Или nohup bash -c 'npm start' &

Как я понял

Без реакт
const cars = [ { name: 'BMW M2 Coupe', price: 20000, img: 'https://mochamanstyle.com/wp-content/uploads/2015/10/2016-BMW-M2-Coupe.jpg' }, { name: 'Audi TT', price: 15000, img: 'https://article.images.consumerreports.org/w_598,h_436/prod/content/dam/cro/news_articles/cars/2016-Audi-TT-pr-1-2016-598' }, { name: 'Rolls Royce', price: 50000, img: 'http://cdn-ds.com/stock/2017-Bentley-Continental-GT-V8-Coupe--Beverly-Hills-CA/seo/VAMP16966-SCBFT7ZA0HC061335/sz_108215/image-1.jpg' }, { name: 'Mercedes amg coupe', price: 18000, img: 'https://auto.ndtvimg.com/car-images/big/mercedes-amg/gle-coupe/mercedes-amg-gle-coupe.jpg?v=2' } ] function createCar(car) { return ` <div class="card"> <div class="card-img"> <img src="${car.img}" alt="${car.name}"> </div> <h3>${car.name}</h3> <p>${car.price} $</p> </div> ` } function show(text, ob){ if(!ob) return; ob.innerHTML = text; } const templates = cars.map(car => createCar(car)) const html = templates.join(' ') show(html, document.getElementById('root')) //document.querySelector('.list').innerHTML = html
С реакт добавляем в заголовок подключение библиотек
<script src="https://unpkg.com/react@17/umd/react.development.js"></script> <script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script> <!-- Don't use this in production: --> <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script> тут пример
function Car(props) { return ( <div className="card"> <div className="card-img"> <img src={props.car.img} alt={props.car.name} /> </div> <h3>{props.car.name}</h3> <p>{props.car.price} $</p> </div> ) } const app = ( <div className="app"> <div className="list"> <Car car={{ name: 'BMW M2 Coupe', price: 20000, img: 'https://mochamanstyle.com/wp-content/uploads/2015/10/2016-BMW-M2-Coupe.jpg' }} /> <Car car={{ name: 'Audi TT', price: 15000, img: 'https://article.images.consumerreports.org/w_598,h_436/prod/content/dam/cro/news_articles/cars/2016-Audi-TT-pr-1-2016-598' }}/> <Car car={{ name: 'Rolls Royce', price: 50000, img: 'http://cdn-ds.com/stock/2017-Bentley-Continental-GT-V8-Coupe--Beverly-Hills-CA/seo/VAMP16966-SCBFT7ZA0HC061335/sz_108215/image-1.jpg' }}/> <Car car={{ name: 'Mercedes amg coupe', price: 18000, img: 'https://auto.ndtvimg.com/car-images/big/mercedes-amg/gle-coupe/mercedes-amg-gle-coupe.jpg?v=2' }}/> </div> </div> ) ReactDOM.render(app, document.getElementById('root'))
где реакт в виде класса
function Car(props) { return ( <div className="card"> <div className="card-img"> <img src={props.car.img} alt={props.car.name} /> </div> <h3>{props.car.name}</h3> <p>{props.car.price} $</p> </div> ) } class App extends React.Component { state = { cars: [ { name: 'BMW M2 Coupe', price: 20000, img: 'https://mochamanstyle.com/wp-content/uploads/2015/10/2016-BMW-M2-Coupe.jpg' }, { name: 'Audi TT', price: 15000, img: 'https://article.images.consumerreports.org/w_598,h_436/prod/content/dam/cro/news_articles/cars/2016-Audi-TT-pr-1-2016-598' }, { name: 'Rolls Royce', price: 50000, img: 'http://cdn-ds.com/stock/2017-Bentley-Continental-GT-V8-Coupe--Beverly-Hills-CA/seo/VAMP16966-SCBFT7ZA0HC061335/sz_108215/image-1.jpg' }, { name: 'Mercedes amg coupe', price: 18000, img: 'https://auto.ndtvimg.com/car-images/big/mercedes-amg/gle-coupe/mercedes-amg-gle-coupe.jpg?v=2' } ] } renderCars() { return this.state.cars.map(car => { return ( <Car car={car} key={car.name + Math.random()} /> ) }) } render() { return ( <div className="app"> <div className="list"> { this.renderCars() } </div> </div> ) } } ReactDOM.render(<App />, document.getElementById('root'))

Как работает jsx

Без него было бы так
const e = React.createElement function Car(props) { return e('div', {className: 'card'}, [ e('div', {className: 'card-img', key: 'div'}, e('img', {src: props.car.img, alt: props.car.name})), e('h3', {key: 'h3'}, props.car.name), e('p', {key: 'ppp'}, props.car.price) ]) } class App extends React.Component { state = { cars: [ { name: 'BMW M2 Coupe', price: 20000, img: 'https://mochamanstyle.com/wp-content/uploads/2015/10/2016-BMW-M2-Coupe.jpg' }, { name: 'Audi TT', price: 15000, img: 'https://article.images.consumerreports.org/w_598,h_436/prod/content/dam/cro/news_articles/cars/2016-Audi-TT-pr-1-2016-598' }, { name: 'Rolls Royce', price: 50000, img: 'http://cdn-ds.com/stock/2017-Bentley-Continental-GT-V8-Coupe--Beverly-Hills-CA/seo/VAMP16966-SCBFT7ZA0HC061335/sz_108215/image-1.jpg' }, { name: 'Mercedes amg coupe', price: 18000, img: 'https://auto.ndtvimg.com/car-images/big/mercedes-amg/gle-coupe/mercedes-amg-gle-coupe.jpg?v=2' } ] } renderCars() { return this.state.cars.map(car => { return e(Car, {car: car, key: car.name + Math.random()}) }) } render() { return e( 'div', {className: 'app'}, e( 'div', {className: 'list'}, this.renderCars() ) ) } } ReactDOM.render(e(App), document.getElementById('root'))

Как добавить клик

function Car(props) { const classes = ['card'] if (props.car.marked) { classes.push('marked') } return ( <div className={classes.join(' ')} onClick={props.onMark}> <div className="card-img"> <img src={props.car.img} alt={props.car.name} /> </div> <h3>{props.car.name}</h3> <p>{props.car.price} $</p> </div> ) } class App extends React.Component { state = { cars: [ { marked: false, name: 'BMW M2 Coupe', price: 20000, img: 'https://mochamanstyle.com/wp-content/uploads/2015/10/2016-BMW-M2-Coupe.jpg' }, { marked: false, name: 'Audi TT', price: 15000, img: 'https://article.images.consumerreports.org/w_598,h_436/prod/content/dam/cro/news_articles/cars/2016-Audi-TT-pr-1-2016-598' }, { marked: false, name: 'Rolls Royce', price: 50000, img: 'http://cdn-ds.com/stock/2017-Bentley-Continental-GT-V8-Coupe--Beverly-Hills-CA/seo/VAMP16966-SCBFT7ZA0HC061335/sz_108215/image-1.jpg' }, { marked: false, name: 'Mercedes amg coupe', price: 18000, img: 'https://auto.ndtvimg.com/car-images/big/mercedes-amg/gle-coupe/mercedes-amg-gle-coupe.jpg?v=2' } ] } handleMarked(name) { const cars = this.state.cars.concat() const car = cars.find(c => c.name === name) car.marked = !car.marked this.setState({ cars }) } renderCars() { return this.state.cars.map(car => { return ( <Car car={car} key={car.name + Math.random()} onMark={this.handleMarked.bind(this, car.name)} /> ) }) } render() { return ( <div className="app"> <div className="list"> { this.renderCars() } </div> </div> ) } } ReactDOM.render(<App />, document.getElementById('root'))
доп кнопка
function Car(props) { const classes = ['card'] if (props.car.marked) { classes.push('marked') } return ( <div className={classes.join(' ')} onClick={props.onMark}> <div className="card-img"> <img src={props.car.img} alt={props.car.name} /> </div> <h3>{props.car.name}</h3> <p>{props.car.price} $</p> </div> ) } class App extends React.Component { state = { cars: [ { marked: false, name: 'BMW M2 Coupe', price: 20000, img: 'https://mochamanstyle.com/wp-content/uploads/2015/10/2016-BMW-M2-Coupe.jpg' }, { marked: false, name: 'Audi TT', price: 15000, img: 'https://article.images.consumerreports.org/w_598,h_436/prod/content/dam/cro/news_articles/cars/2016-Audi-TT-pr-1-2016-598' }, { marked: false, name: 'Rolls Royce', price: 50000, img: 'http://cdn-ds.com/stock/2017-Bentley-Continental-GT-V8-Coupe--Beverly-Hills-CA/seo/VAMP16966-SCBFT7ZA0HC061335/sz_108215/image-1.jpg' }, { marked: false, name: 'Mercedes amg coupe', price: 18000, img: 'https://auto.ndtvimg.com/car-images/big/mercedes-amg/gle-coupe/mercedes-amg-gle-coupe.jpg?v=2' } ], visible: true } handleMarked(name) { const cars = this.state.cars.concat() const car = cars.find(c => c.name === name) car.marked = !car.marked this.setState({ cars }) } toggleHandler() { this.setState({visible: !this.state.visible}) } renderCars() { if (!this.state.visible) { return null } return this.state.cars.map(car => { return ( <Car car={car} key={car.name + Math.random()} onMark={this.handleMarked.bind(this, car.name)} /> ) }) } render() { return ( <div className="app"> <button onClick={() => this.toggleHandler()}>Toggle</button> <hr/> <div className="list"> { this.renderCars() } </div> </div> ) } } ReactDOM.render(<App />, document.getElementById('root'))

Input

function Car(props) { const classes = ['card'] if (props.car.marked) { classes.push('marked') } return ( <div className={classes.join(' ')} onClick={props.onMark}> <div className="card-img"> <img src={props.car.img} alt={props.car.name} /> </div> <h3>{props.car.name}</h3> <p>{props.car.price} $</p> </div> ) } class App extends React.Component { state = { cars: [ { marked: false, name: 'BMW M2 Coupe', price: 20000, img: 'https://mochamanstyle.com/wp-content/uploads/2015/10/2016-BMW-M2-Coupe.jpg' }, { marked: false, name: 'Audi TT', price: 15000, img: 'https://article.images.consumerreports.org/w_598,h_436/prod/content/dam/cro/news_articles/cars/2016-Audi-TT-pr-1-2016-598' }, { marked: false, name: 'Rolls Royce', price: 50000, img: 'http://cdn-ds.com/stock/2017-Bentley-Continental-GT-V8-Coupe--Beverly-Hills-CA/seo/VAMP16966-SCBFT7ZA0HC061335/sz_108215/image-1.jpg' }, { marked: false, name: 'Mercedes amg coupe', price: 18000, img: 'https://auto.ndtvimg.com/car-images/big/mercedes-amg/gle-coupe/mercedes-amg-gle-coupe.jpg?v=2' } ], visible: true, appTitle: 'Cars application' } handleMarked(name) { const cars = this.state.cars.concat() const car = cars.find(c => c.name === name) car.marked = !car.marked this.setState({ cars }) } toggleHandler() { this.setState({visible: !this.state.visible}) } renderCars() { if (!this.state.visible) { return null } return this.state.cars.map(car => { return ( <Car car={car} key={car.name + Math.random()} onMark={this.handleMarked.bind(this, car.name)} /> ) }) } titleChangeHandler(title) { if (title.trim() === '') { return } this.setState({ appTitle: title }) } render() { const style = { marginRight: 20 } return ( <div className="app"> <h1>{this.state.appTitle}</h1> <button onClick={() => this.toggleHandler()} style={style} >Toggle</button> <input type="text" placeholder="Change title" onChange={(event) => this.titleChangeHandler(event.target.value)} value={this.state.appTitle} /> <hr/> <div className="list"> { this.renderCars() } </div> </div> ) } } ReactDOM.render(<App />, document.getElementById('root'))

Пример с состоянием

class Check extends React.Component { constructor(props) { super(props); this.state = { checked: true, }; }; handleCheck = () => { this.setState({checked: !this.state.checked}); }; render() { var message; if (this.state.checked) { message = 'выбран'; } else { message = 'не выбран'; } return ( <div> <input type="checkbox" onChange={this.handleCheck} defaultChecked={this.state.checked} /> <p>Чекбокс {message}</p> </div> ); } }

Большой пример с передачей функций

class Task extends React.Component { state = {edit:false}, edit: function(){ this.setState({edit:true}) }, remove: function(){ this.props.deleteBlock(this.props.index) }, save: function(){ this.props.update(this.refs.newTxt.value, this.props.index) this.setState({edit:false}) }, rendNorm:function(){ return ( <div className="box"> <div className="text">{this.props.children}</div> <button onClick="{this.edit}" className="btn light">Редактировать</button> <button onClick="{this.remove}" className="btn red">Удалить</button> </div> ) }, rendEdit: function(){ return ( <div className="box"> <textarea ref="newTxt" defaultValue={this.props.children}></textarea> <button onClick="{this.save}" className="btn success">Сохранить</button> </div> ) }, render: function(){ if(this.state.edit) return this.rendEdit() return this.rendNorm() } } class Field extends React.Component { state = {tasks:['t1','t2','t3']}, add: function(text){ tasks = this.state.tasks tasks.push(text) this.setState({tasks}) }, deleteBlock: function(i){ tasks = this.state.tasks tasks.splice(i, 1) this.setState({tasks}) // this.setState({tasks:tasks}) }, updateText: function(text, i){ tasks = this.state.tasks tasks[i] = text this.setState({tasks}) }, eachTask: function(item, i){ return ( <Task key={i} index={i}>{item}</Task> ) }, render: function(){ return ( <div className="field"> <button onClick="{this.add.bind(null, 't4')}" className="btn newTask">Добавить</button> {this.state.tasks.map(this.eachTask)} </div> ) } }