Notes of React 2

React ref

4th Set JSDB

1. install json server

create a new folder

copy json file from GitHub

1
2
3
yarn add json-server
npx json-server --watch db.json --port 3003
// since we don't have json setting file here, 'yarn start' may not be able to set the port

2. Add API

in products.js

Install axios

yarn add axios

import axios from 'axios';

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import axios from 'commons/axios';

state = {
products : [
]
} // set state empty so we can 重新渲染 later


componentDidMount() {
axios.get('/products') // 已经配置好不用加prefix
.then(response => this.setState({
products: response.data
}));
}

new file in commons to set axios

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import _axios from "axios";

const axios = (baseURL) => {
const instance = _axios.create({
baseURL: baseURL || "http://localhost:3003",
timeout: 1000,
});

return instance;
};

export { axios };

export default axios();

3. Search Product

In toolbox.js, change text into controlled component

In Products.js, create search function (because search function is to filter all the products)

// 1. Get New Array

// 2. Filter New Array

用match搜索

// 3. set State

得到新的products数组的值,重新渲染UI

5th Add animation effects to products

products wrapped by Transition Group (多个元素)

用CSSTransition包裹单个元素

1
<CSSTransition classNames="product-fade" timeout={300} key={p.id}> //classNames 是前缀,timeout是渐进时间,key是区分每个product

6th POP window

首先构建页面,然后添加ADD, EDIT, DELETE 功能

https://github.com/typicode/json-server (json-server instruction)

children component 调用父组件函数 button

构建表单,通过表单传递信息给API,重新渲染页面

构建可控组建:

新建

1
2
3
4
5
6
7
state = {
name: '',
price: '',
tags: '',
image: '',
status: 'available'
};

然后新建

1
2
3
4
5
6
7
handleChange = e => {
const value = e.target.value;
const name = e.target.name;
this.setState({
[name]: value
});
};

然后绑定

1
2
3
4
5
6
<textarea
className="textarea"
name="name"
value={this.state.name} // 和state里面的attribute对应
onChange={this.handleChange}
/>

用submit函数获取表单数据

1
2
3
4
5
6
7
8
submit = e => {
e.preventDefault(); //阻止默认行为
const product = { ...this.state }; //获取state数据
axios.post('products', product).then(res => {
this.props.close(res.data);
toast.success('Add Success');
}); //post方法提交到REST API
};

ToastContainer使用

https://fkhadra.github.io/react-toastify/introduction

container在index.js导入,与Router同级,用一个div包裹

toast放在AddInventory.js

Edit Inventory

https://developer.mozilla.org/en-US/docs/Web/JavaScript

similar to Addinventory, but need to put the existed info to the form

And write the update fuction in Products.js (为了实时更新)

first find the product we need to update (find index), and then update the product list and source list based on the changed info

子组件调用父组件可以通过参数传递

delete函数从products 传递到product

1
2
3
4
5
6
7
8
delete = id => {
const _products = this.state.products.filter(p => p.id !== id);
const _sProducts = this.state.sourceProducts.filter(p => p.id !== id);
this.setState({
products: _products,
sourceProducts: _sProducts
});
};

<Product product={p} update={this.update} delete={this.delete}></Product> (已经传递给product组件)

从product传递到EditInventory

toEdit里props加一个deleteProduct: this.props.delete

delete btn bind onClick={this.onDelete}

7th Cart

async function查找是否product已经在购物车里

状态提升,toolbox和product都是products的子组件,是兄弟组件,所以把state里面的cartNum 提高到父组件products进行处理。

8th JWT

update

import useForm from 'react-hook-form';

to

import { useForm } from 'react-hook-form';

update

const { register, handleSubmit, errors } = useForm();

to

const { register, handleSubmit, formState: { errors } } = useForm();

9th Deploy

deploy on zeit.co

install now sudo npm install -g now

connect your github account with zeit

change “scripts” in package.json to

1
2
3
4
5
6
7
"scripts": {
"start": "serve --single ./build", //build目录下 单页面
"dev": "react-scripts start",
"build": "react-scripts build", // 打包
"test": "react-scripts test",
"eject": "react-scripts eject"
},

install serve in vscode

yarn add serve

then

now