1. 特点
1.1. 特征
- 支持JXS
- 支持TypeScript
1.2. 优点
- 函数式
- 组件化
1.3. 缺点
- 学习成本较高
- 基础要求高
2. 语法
2.1. 渲染元素
<id="root"></>
<script type="text/babel">
let element = <>Hello World</>;
let root = $('#root').get(0);
ReactDOM.render(element, root);
</script>
2.2. 组件声明
class Test extends React.Component {
render() {
return <>1</>;
}
}
let element = <Test />;
2.3. 组件传参
class Test extends React.Component {
render() {
return <>{this.props.data}</>;
}
}
let element = <Test data="test" />;
2.4. 组件嵌套
class Child extends React.Component {
render() {
return <>{this.props.data}</>
}
}
class Parent extends React.Component {
render() {
return (
<>
<Child data="1" />
<Child data="2" />
</>
);
}
}
2.5. 生命周期
class Test extends React.Component {
constructor(props) {super(props);} // 构造函数
componentWillMount() {} // 将挂载组件
componentDidMount() {} // 已挂载组件
componentWillUnmount() {} // 将卸载组件
componentWillReceiveProps (nextProps) {} // 接收数据
getDerivedStateFromProps(nextProps, prevState) {} // 获取更新数据
shouldComponentUpdate(nextProps, nextState) {} // 是否更新数据
componentWillUpdate (nextProps, nextState) {} // 将更新数据 可能不被渲染
getSnapshotBeforeUpdate(prevProps, prevState) {} // 将更新数据 肯定被渲染
render() {} // 渲染
componentDidUpdate(prevProps, prevState) {} // 已更新数据
}
2.6. 绑定事件
class Test extends React.Component {
constructor(props) {
super(props);
this.state = {number: 0};
this.click = this.click.bind(this);
}
click() {
this.setState({
number: this.state.number + 1,
});
}
render() {
return <button onClick={this.click}>{this.state.number}</button>;
}
}
2.7. 表单
class Form extends React.Component {
constructor(props) {
super(props);
this.state = {
text: '',
number: '',
date: '',
time: '',
file: '',
password: '',
checkbox: '',
radio: '',
textarea: '',
select: '',
};
this.handleInputChange = this.handleInputChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleInputChange (event) {
const target = event.target;
const name = target.name;
const value = ['checkbox', 'radio'].indexOf(target.type) == -1 ? target.value : target.checked;
this.setState({[name]: value});
}
handleSubmit(event) {
console.log(this.state);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<input type="text" name="text" value={this.state.text} onChange={this.handleInputChange} />
<input type="number" name="number" value={this.state.number} onChange={this.handleInputChange} />
<input type="date" name="date" value={this.state.date} onChange={this.handleInputChange} />
<input type="time" name="time" value={this.state.time} onChange={this.handleInputChange} />
<input type="file" name="file" value={this.state.file} onChange={this.handleInputChange} />
<input type="password" name="password" value={this.state.password} onChange={this.handleInputChange} />
<input type="checkbox" name="checkbox" checked={this.state.checkbox} onChange={this.handleInputChange} />
<input type="radio" name="radio" checked={this.state.radio} onChange={this.handleInputChange} />
<textarea name="textarea" value={this.state.textarea} onChange={this.handleInputChange} />
<select name="select" value={this.state.select} onChange={this.handleInputChange}>{[1, 2].map((v, k) => <option key={k} value={k}>{v}</option>)}</select>
<input type="submit" value="Submit" />
</form>
);
}
}
2.8. 调用父组件
class A extends React.Component {
render() {
return <button onClick={() => this.props.case(this.props.data)}>{this.props.data}</button>;
}
}
class B extends React.Component {
constructor(props) {
super(props);
this.show = (e) => alert(e);
}
render() {
return (
<>
<A data="1" case={this.show} />
<A data="2" case={this.show} />
</>
);
}
}
2.9. 继承
class A extends React.Component {
render() {
return <>{this.props.children}</>;
}
}
class B extends React.Component {
render() {
return (
<A>
<>{this.props.one}</>
{this.props.two}
{this.props.children}
</A>
);
}
}
class C extends React.Component {
constructor(props) {
super(props);
this.state = {text: '2'};
}
render() {
return (
<B one="1" two={<input value={this.state.text} onChange={(e) => this.setState({text: e.target.value})} />}>
<button onClick={() => alert(`${this.state.text}`)}>3</button>
</B>
);
}
}
3. JSX
3.1. 运算
let element = <>{1 + 2}</>;
3.2. 判断
let element = <>{true ? 1 : 0}</>;
3.3. 样式表
let style = {
color: '#00f',
};
let element = <style={style}>Hello</>;
3.4. 数组
let arr = [
<>1</>,
<>2</>,
];
let element = <>{arr}</>;
3.5. 判断
let element = (
<>
{true && <>1</>}
{false ? <>2</> : <>3</>}
</>
);
3.6. 循环
const arr = [1, 2, 3];
const lis = arr.map((v, k) => <key={k}>{v}</>);
let element = <>{lis}</>;
4. React Hooks
4.1. 普通变量
import { useState } from 'react';
const [test, setTest] = useState({});
4.2. 状态变量
import { useReducer } from 'react';
const init = {test: 0};
function reducer(state, action) {
switch(action.type) {
case: 'test': return {...state, test: 1};
default: throw new Error();
}
}
function Test() {
const [state, dispatch = useReducer(reducer, init);
return <onClick={() => dispatch({type: 'test'})></>;
}
4.3. 事件
import { useEffect } from 'react';
import { useLayoutEffect } from 'react';
import { useCallback } from 'react';
import { useMemo } from 'react';
useEffect(() => {}); // 异步事件
useEffect(() => {}, []); // 调用限制
useEffect(() => ({})); // 卸载清除
useLayoutEffect(() => {}); // 渲染前执行
const callback = useCallback(() => {}); // 限制回调
const memo = useMemo(() => {}); // 限制处理
4.4. 上下文
import { createContext } from 'react';
import { useContext } from 'react';
const TestContext = createContext(0);
function Parent() {
return <TestContext.Provider value={1}><Child /></TestContext.Provider>;
}
function Child() {
const test = useContext(TestContext);
return <>{test}</>;
}
4.5. Ref对象
import { useRef } from 'react';
const ref = useRef(null);
let element = <input type="text" ref={ref} />;
4.6. Ref函数
import { useRef } from 'react';
import { useImperativeHandle } from 'reac';
import { forwardRef } from 'react';
const Child = forwardRef((props, ref) => {
const r = useRef();
useImperativeHandle(ref, () => ({
f: () => {
r.current.focus();
},
}));
return <input type="text" ref={r}>;
});
function Parent() {
const r = useRef();
return <><onClick={() => r.current.f()}>Click</><Parent ref={r}></>
}
5. React Router
5.1. 关联URL
import { BrowserRouter } from 'react-router-dom"
let element = <BrowserRouter></></BrowserRouter>;
5.2. 添加链接
import { Link } from 'react-router-dom';
let element = <Link to="/">Index</Link>;
5.3. 链接状态
import { NavLink } from 'react-router-dom';
let element = <NavLink>{isActive}</NavLink>;
5.4. 添加路由
import { Routes } from 'react-router-dom';
import { Route } from 'react-router-dom';
let element = <BrowserRouter><Routes><Route path="/" element={</>} /></Routes></BrowserRouter>;
5.5. 路由嵌套
import { Outlet } from 'react-router-dom';
let element = <Route path="/" element={</>}><Route path="test" element={</>} /></Route><Outlet />;
5.6. 路由循环
let element = {[1, 2, 3].map((v, k) => (<Link to={`/${v}`} key={k}>{v}</Link>))};
5.7. 路由通配符
let element = <Route path="*" element={</} />;
5.8. 路由参数
let element = <Route path=":id" element={<Test />} />;
import { useParams } from 'react-router-dom';
export default function Test() {
return <>{useParams().id}</>;
}
5.9. 路由搜索
import { useSearchParams } from 'react-router-dom';
let [searchParams, setSearchParams] = useSearchParams();
5.10. 路由刷新
import { useNavigate } from 'react-router-dom';
let navigate = useNavigate();
let element = <onClick={() => navigate('/test')} />;
6. React Que
6.1. 开发工具
import { ReactQueryDevtools } from 'react-query/devtools';
let element = <ReactQueryDevtools />;
6.2. 查询数据
import { useQuery } from 'react-query';
import { QueryClient } from 'react-query';
import { QueryClientProvider } from 'react-query';
const queryClient = new QueryClient();
function Parent() {
return (
<QueryClientProvider client={queryClient}>
<Child />
</QueryClientProvider>
);
}
function Child() {
const { isLoading, isError, data, error } = useQuery('key', () => 0);
if(isLoading) {
return <>Loading</>
} else if (isError) {
return <>{error.message}</>
} else {
return <>{data}</>
}
}
6.3. 改变数据
import { useMutation } from 'react-query';
const mutation = useMutation((data) => axios.post('/api', data));
mutation.mutate({});
6.4. 常用参数
useQuery(['key', 1, {test: true}], () => 0); // 数组键值
useQuery(['key', {a, b}], ({ params }) => {const [_key, { a, b }] = params}); // 函数传参
useQuery({queryKey: ['key', 1], queryFn: () => 0}); // 对象参数
useQuery('key', () => 0, {enabled: true}); // 是否启用
useQuery('key', () => 0, {retry: 10}); // 重试十次
useQuery('key', () => 0, {retry: false}); // 禁止重试
useQuery('key', () => 0, {retry: true}); // 无限重试
useQuery('key', () => 0, {retry:(count,error)=> true}); // 自定义重试
useQuery('key', () => 0, {keepPreviousData: true}); // 保留前次数据
useQuery('key', () => 0, {initialData: []}); // 初始化数据
useQuery('key', () => 0, {onSuccess: () => {}}); // 执行成功
useQuery('key', () => 0, {onError: () => {}}); // 执行失败
useQuery('key', () => 0, {onSettled: () => {}}); // 执行结束
6.5. 批量查询
import { useQueries } from 'react-query';
const tests = useQueries(
[{id:1},{id:2},{id:3}].forEach((val) => {
return {
queryKey: ['test', val.id],
queryFn: () => fetchUserById(val.id),
};
}),
);
6.6. 失效查询
import { useQueryClient } from 'react-query';
const queryClient = useQueryClient();
queryClient.invalidateQueries('test');
6.7. 直接更新
import { useQueryClient } from 'react-query';
const queryClient = useQueryClient();
queryClient.setQueryData([test], 1);
7. Redux
7.1. Action
let action = () => {
return {
type: '',
};
}
7.2. Reducer
let reducer = (state = {}, action) => {
switch (action.type) {
case '':
return {
...state,
};
default:
return state;
}
}
7.3. Store
import { createStore } from 'redux';
let store = createStore(reducer); // 创建
let test = store.getState(); // 获取数据
store.dispatch(action); // 发出行为(更新数据)
const unsubscribe = store.subscribe(() => {}); // 监听行为
unsubscribe(); // 停止监听
7.4. React Redux
import { Provider } from 'react-redux';
import { connect } from 'react-redux';
let Receiver = connect(state => state, null)((props) => <></>); // 获取数据
let Sender = export default connect(null, (dispatch) => { // 发出行为(更新数据)
return {send: () => dispatch({type: 'add_action'})}
})((props) => <button onClick={() => props.send()}>+</button>);
let App = (
<Provider store={store}>
<Sender />
<Receiver />
</Provider>
);
7.5. API
import { combineReducers } from 'react-redux';
let reducers = combineReducers({reducer, reducer});
import { bindActionCreators } from 'react-redux';
let dispatch = bindActionCreators({reducer, reducer}, dispatch);
import { applyMiddleware } from 'react-redux';
import { compose } from 'react-redux';
let store = createStore(reducer, [preloadedState], enhancer);
let enhancer = applyMiddleware(m1, m2);
let func = compose(m1, m2);
import { connect } from 'react-redux';
let component = connect([mapStateToProps], [mapDispatchToProps], [mergeProps], [options]);
let mapStateToProps = (state) => ({});
let mapDispatchToProps = (dispatch, ownProps) => ({test: () => dispatch({type: ''})});
let mergeProps = (stateProps, dispatchProps, ownProps) => ({});
import { useStore } from 'react-redux';
import { useSelector } from 'react-redux';
import { useDispatch } from 'react-redux';
let store = useStore();
let value = useSelector(state => state.value);
let dispatch = useDispatch();
7.6. Redux Middleware
import thunk from 'redux-thunk';
import promise from 'redux-promise';
import logger from 'redux-logger';
const store = createStore(reducers, applyMiddleware(thunk, promise, logger));
参考
版权协议

本作品采用知识共享署名-非商业性使用-禁止演绎 3.0 版本许可协议进行许可。