从零开始React-01
以前忽略的地方
- 当前文件夹的格式是:“ . / ”。注意有个点
" . / folderName"
- 没有括号()!!
class App extends Component { }
//没有括号()!!
- render中的return()
render(){
return (<div>记住</div>)
}
使用Antd添加样式
- 加载antd包:npm install antd --save
- 在App.jsx上面添加两条语句:
import { 待使用的组件名 } from ‘antd’;
import ‘antd/dist/antd.css’;
- 在App.jsx中使用组件<组件名/>(盲点:CSS样式要用{{ }})
<Input placeholder="请输入内容" style={{ width: "400px",marginRight:"10px"}} />
redux
- 首先npm install redux --save,引入redux包
- src下创建store文件夹,文件夹内一个index.js一个reducer.js
-Todolist.jsx中上面补充import store from “./store/index.js”,并且在组件中加入store.getState()
//store的入口文件index.js
import { legacy_createStore as createStore } from 'redux'
//上面这一语句必须,以往的import { createStore } from 'redux'已失效
import reducer from "./reducers";
const store = createStore(reducer);
export default store;
//store文件夹下的reducer.js文件,它并不引入任何依赖包
const defaultState = {
inputValue: "123",
list:[1,2,3]
};
export default (state=defaultState,action) => {
return state;
}
//Todolist组件,(局部)
class Todolist extends Component {
constructor(props) {
super(props);
this.state = store.getState();//获取store中的内容
// console.log(store.getState());
}
redux调试工具相关
- chrome浏览器中安装插件:redux devtools
- 安装完之后有两种方式使该插件生效。如下分别为法1、法2
- 在store的入口文件index.js的
createStore(reducer,参数2)
中,参数2的位置换成:window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
- 在项目文件中npm install --save-dev redux-devtools-extension。之后来到store的入口文件index.js中,引入该依赖包
import {composeWithDevTools} from "redux-devtools-extension"
,然后在createStore(reducer,参数2)
的参数2的位置,换成composeWithDevTools()
如果这一位置原来就有函数fn,则把参数2的函数换成composeWithDevTools(fn)
即可,最后完整版语句即createStore(reducer,composeWithDevTools(fn))
redux:store、action与reducer的交互
拿inputchange这一交互事件来举例
- 必要的准备
<Input
value={this.state.inputValue}
onChange={this.handleInputChange}//Input组件增加一个函数
/>
constructor(props) {
super(props);
this.state = store.getState();
this.handleInputChange = this.handleInputChange.bind(this);增加函数指向转换语句
}
- Todolist组件中添加这一函数,并在函数内Action Creator,这样一有变化就会发送给store,而store也会自动地将变化传给reducer
handleInputChange(e) {
const action = {
type: "change_input_value",//这是自己起的名
value: e.target.value//将变换后的输入值传给action
}
store.dispatch(action);//将action传给store;
}
- store将action传给reducer后,reducer首先对原state进行深复制以待修改,修改完成之后再返回newState给store
export default (state = defaultState, action) => {
if (action.type == "change_input_value") {
//reducer可以接受state,但不能修改state
//必须对state做一个深复制(互不相干扰),避免对原state干扰
let newState = { ...state };
newState.inputValue = action.value;
return newState;
}
return state;
}
- 关键点!!!更新store内的状态。store.subscribe()!!!.只要store的状态发生改变,subscribe内的函数就能立刻执行。
class Todolist extends Component {
constructor(props) {
super(props);
this.state = store.getState();
this.handleInputChange = this.handleInputChange.bind(this);
this.handleStoreChange = this.handleStoreChange.bind(this);
store.subscribe(this.handleStoreChange);//store的状态一旦发生改变就会触发subscribe内的函数
}
render() {(...)}
handleInputChange(e) {
const action = {//定义action
type: "change_input_value",
value: e.target.value
}
store.dispatch(action);向store发送action,store再向reducer发送action
}
handleStoreChange() {
this.setState(() => store.getState());
/* 这样写也行: this.setState( store.getState() ) */
}
}