React

Redux Toolkit

October 28, 2019
React

Redux Toolkit是 Redux 官方提供的工具箱🧰,它指定了一个 Redux 的使用规则,集成了 immer thunk 等常用的工具库,还有很好的 typescript 支持。 slice 安装 # yarn add @reduxjs/toolkit // 或者 npx create-react-app my-app --template redux 初始化store # 1 2 3 4 5 6 7 8 import { configureStore, createReducer } from 'redux-starter-kit'; export const add = createAction('add') const initialState = { number: 0 } const reducer = createReducer(initialState, { [add]: (state, action) => state.number = action.number, }) const store = configureStore({reducer}) export default store; 调用 # 1 2 3 4 5 6 7 8 // . ...

React Spring

October 22, 2019
React, React库

react-spring 是一个基于弹簧物理学的动画库。 最基本的用法: 1 2 3 4 5 6 import {useSpring, animated} from 'react-spring' function App() { const props = useSpring({opacity: 1, from: {opacity: 0}}) return <animated.div style={props}>I will fade in</animated.div> } 其中的useSpring可以创造一个js动画,这种动画默认不需要设置持续时间,他通过一些弹簧参数来控制动画的表现。可以通过config设置这些参数,像这样: 1 useSpring({ config: { duration: 250 }, ... }) 参数有哪些可以看Common api这节文档。 1 useSpring({opacity: 1, from: {opacity: 0}}) from为动画开始的值,1为动画最后的值。 1 useSpring({opacity: 1, to: {opacity: 0}}) 1为动画开始的值,to为动画最后的值。 如果useSpring中变化的值可以直接使用,比如颜色、数字,则可以直接使用 1 <animated.div style={props}>I will fade in</animated.div> 或这样 1 <animated.span>{props.number}</animated.span> 如果useSpring中变化的值需要组合成字符串,比如transform,则需要使用插值函数(interpolate)来实现 ...

React Rangeslider

August 28, 2019
React, React库

官网 使用 # yarn add react-rangeslider --save 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 import Slider from 'react-rangeslider' import 'react-rangeslider/lib/index.css' <Slider min={0} max={100} value={value} onChangeStart={this.handleChangeStart} onChange={this.handleChange} onChangeComplete={this.handleChangeComplete} /> <Slider min={0} max={10} value={reverseValue} orientation='horizontal' onChange={this.handleChangeReverse} />

React Popup

August 22, 2019
React, React库

React Popup 是一个弹窗组件的库。 安装 # yarn add reactjs-popup npm install reactjs-popup 基本用法 # contentStyle:设置内容区的样式 overlayStyle:设置遮罩的样式 占位弹窗1 # 1 2 3 4 5 6 7 8 import React from "react"; import Popup from "reactjs-popup"; const PopupExample = () => ( <Popup trigger={<button> Trigger</button>} position="right center"> <div>Popup content here !!</div> </Popup> ); 占位弹窗2 # 1 2 3 4 5 6 7 8 9 10 11 12 const PopupExample = () => ( <Popup trigger={<button>Trigger</button>} position="top left"> {close => ( <div> Content here <a className="close" onClick={close}> &times; </a> </div> )} </Popup> ); 受控Modal # 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 const Modal = () => ( <div> <button className="button" onClick={this. ...

利用useContext使用ReactRouter

July 8, 2019
React
api

React Router 的history.push # 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 import React, { useState, useContext, useEffect } from 'react'; import { __RouterContext } from "react-router"; const Login: React.FC = () => { const [token, setToken] = useState(''); const { history } = useContext(__RouterContext); useEffect(() => { if (token) { history.push('/list') } }, [token, history]); return ( <> <button onClick={()=>setToken('666')}>登录</button> </> ); } 这段代码的逻辑是,等级登录按钮,设置token变量。当token变量变化时,触发useEffect调用ReactRouter的history. ...

React 与 Typescript

January 20, 2019
React

input的事件类型 # 需要注意两点。 事件类型可能有两种 ChangeEvent 对应 event.target FormEvent 对应 event.currentTarget 泛型对应元素,可能是HTMLInputElement 或 HTMLSelectElement 等。 1 2 3 4 5 6 const handleSearch = (event: React.ChangeEvent<HTMLInputElement>) => { if (event.target.value) { setKeywords(event.target.value); props.onUpdateKeyword(event.target.value); } } class组件的类型 # class组件需要定义props和state的类型: interface IProps { addTodo: (input: string) => void; } interface IState { input: string; } class AddTodo extends React.Component<IProps, IState>{} 创建项目 # creact-react-app可以直接创建 typescript 项目。 create-react-app my-app --scripts-version=react-scripts-ts 修改配置 # 把 tslint.json 修改为这样,能舒服一点: ...

Redux Saga

December 2, 2018
React
api

redux-saga中使用fetch # 1 2 3 const response = yield call(fetch, '/consult/v1/headCarousel'); const data = yield response.json(); yield put({ type: 'save', payload: data }); 为了对它有一个感性的认识,首先看一下 中文文档 把dome写出来,跑一下。另外还需要了解 ES6的Generator 。 跑完了文档中的dome之后,在来看一个例子。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 // 类 thunk 的 worker “进程” function* load() { yield put({ type: BEGIN_LOAD_DATA }); try { const result = yield call(fetch, UrlMap.loadData); yield put({ type: LOAD_DATA_SUCCESS ,payload: result }); } catch (e) { yield put({type: LOAD_DATA_ERROR }); } } function* saga() { // 创建一个监听“进程” yield fork(watch(CLICK_LOAD_BUTTON, load)) } 这里有几个 redux-saga 的概念需要再了解一下。 ...