vue tutorial 上的小demo 改用react 写法
<div className={xx}></div>
import React, { useState } from 'react';
export function App(props) {
const [count, setCount] = useState(0)
function add() {
setCount(count + 1)
}
return (
<div className='App'>
<button onClick={add}>add {count}</button>
</div>
);
}
import React, { useState } from 'react';
export function App(props) {
const [val, setVal ] = useState('abc')
return (
<div className='App'>
<input value={val} onChange={(e) => setVal(e.target.value)}/>{ val }
</div>
);
}
import React, { useState } from 'react';
export function App(props) {
const [awesome, setAwesome] = useState(false)
return (
<div className='App'>
<button onClick={() => setAwesome(!awesome)}>toggle</button>
{awesome ? <h1 >Vue is awesome!</h1> : <h1>Oh no </h1>}
</div>
);
}
import { useState } from 'react'
let id = 0
function App() {
const [newTodo, setNewTodo] = useState('')
const [todos, setTodos] = useState([
{ id: id++, text: 'ss' }
])
function addTodo(e) {
e.preventDefault()
setTodos([...todos, { id: id++, text: newTodo }])
setNewTodo('')
}
function removeTodo(todo) {
console.log(todo, todos.filter(i => i !== todo))
setTodos(todos.filter(i => i !== todo))
}
return (
<div className="App">
<form onSubmit={addTodo}>
<input value={newTodo} onChange={(e) => setNewTodo(e.target.value)} />
<button>Add Todo</button>
</form>
<ul>{
todos.map(i => {
return (
<li key={i.id}>
{i.text}
<button onClick={() => removeTodo(i)}>X</button>
<input />
</li>
)
})
}
</ul>
</div>
)
}
export default App
react没有计算属性的概念, 但是可用 useMemo替代
const compToggle = useMemo(() => toggleAll ? todos : todos.filter(i => !i.checked)) // ??
setTodos([...todos]) //
<span className={i.checked ? 'line-trought' : ''}>{i.text}</span>
useEffect(() =>{
console.log('useEffect', count)
console.log('useEffect', person.name)
}, []) // 可以添加想监听的变化. 因为监听了两个变量, 所以调用两次??
import A from 'a'
<A />
props 直接形参接收, 传方法的话, 子组件调用给父组件传参
父调子的话, useRef ref={}
插槽的话可以用 形参的.children 分: 纯文本, 单标签, 多标签的情况
react 是一个构建界面的js库
脚手架创建项目
npm install -g create-react-app || yarn global add
create-react-app aa 用脚手架创建了一个叫aa
用了脚手架搭建框架: 模块化 组件化 工程化.
f
componentWillMount和componentWillUpdate这两个函数往往包含副作用,所以当使用React Fiber的时候一定要重点看这两个函数的实现。
浏览器不支持 export default {} => node 不支持 => 基于node的webpack也不支持
HashRouter / BrowserRouter
拆分common/components/Header.js
store/index.js reducer.js 主仓库
1, 样式组件,标签styled-components
import styled from 'styled-components'
export const BookWrap = styled.div`
.box{
background: red;
}
src/store/reducer.js
const defaultState = {
meau: [
{ id: '1', name: '图书管理', icon: 'book'},
{ id: '2', name: '用户管理', icon: 'user'}
]
}
export default (state = defaultState, action) => {
let newState = JSON.parse(JSON.stringify(state))
switch (action.type) {
default: ;
break
}
return newState
}
reducer.js
import { combineReducers } from 'redux'
import commonReducer from '../common/store/reducer'
export default combineReducers({
common: commonReducer,
})
index.js
import { createStore } from 'redux'
import Reducer from 'reducer'
export default createStore(reducer,
redux的工具代码
)
用户,分类,vip
const a = 'hello
'
使用类就允许我们使用其它特性,例如局部状态、生命周期钩子
受控组件: input随数据变化而变化.
非受控组件: 没用value属性,真实dom控制 用ref代替id
ref={(el) => {this.username = el}}
defaultValue={this.state.username} //非受控组件,设置默认值
defaultChecked
this.refs.username//this.username.value
React.PureComponent(){ 实现简单的性能优化
}
shouldComponentUpadate(nextProps, nextState){
}
state或props变化引起render执行
类定义构造函数,必须先调用父类的构造函数super
props不能修改,state也不允许直接修改,只能做替换.
setState是异步函数,setState合并性.
this.setState((prevState)=>({
conunt: prevState.count + 1;
}, () = > { console.log(11) } )
双向数据绑定
handleChange(e) {
const value = e.target.value;
this.setState( () = >({
inputVal: vale
}))
}
动作派发,换成函数createAction,函数返回对象
事件处理,状态提升
异步处理
1. dispatch之前,做异步操作
2. 借助中间件,让redux支持异步 Middleware