react-笔记
Fragment 占位符标签 使用方法
class => className
className="input"
{/* 注释内容 */}
// 注释内容
dangerouslySetInnerHTML={{__html:item}} 可以解析 html 标签
<li key={item}
onClick={()=>this.handleItemDelete(index)}
dangerouslySetInnerHTML={{__html:item}}>
</li>
htmlFor 点击扩大区域
<label htmlFor="insertArea">输入内容</label>
代码优化 性能优化
this.handleInputChange = this.handleInputChange.bind(this)
onClick={this.handleButtonClick}
旧代码
handleInputChange(e){
// console.log(e.target.value);
this.setState({
inputValue: e.target.value
})
}
handleButtonClick(){
this.setState({
list: [...this.state.list,this.state.inputValue],
inputValue:''
})
}
handleItemDelete(index){
let newList = [...this.state.list]
newList.splice(index,1)
this.setState({
list: newList
})
}
优化后的新代码 this.setState(()=> ({})) 使用这个优化性能
handleInputChange(e){
const inputValue = e.target.value
this.setState(()=> ({
inputValue
}))
}
handleButtonClick(){
this.setState((prevState)=>{
return {
list: [...prevState.list,prevState.inputValue],
inputValue:''
}
})
}
handleItemDelete(index){
this.setState((prevState)=>{
let list = [...prevState.list]
list.splice(index,1)
return {
list
}
})
}
--------------------
传递参数给子组件
return <TodoItem
index={index}
key={index}
content={item}
deleteItem= {this.handleItemDelete} />
接收父组件传递的参数和方法
import React, { Component } from 'react'
export default class TodoItem extends Component {
constructor(props){
super(props)
this.handleClick = this.handleClick.bind(this)
}
render() {
let {content} = this.props
return (
<div onClick={this.handleClick}> {content} </div>
)
}
handleClick(){
let {deleteItem,index} = this.props
deleteItem(index)
}
}
------------------------
propTypes
import PropTypes from 'prop-types'
// 参数校验 / 类型 array,bool,func,number,object,string,symbol,node,element ...
TodoItem.propTypes = {
test:PropTypes.string.isRequired, // 必填
content: PropTypes.string,
deleteItem:PropTypes.func,
index: PropTypes.oneOfType([PropTypes.number,PropTypes.string]) // 既可以是数字 也可以是字符串
}
{this.props.test}
TodoItem.defaultProps = {
test:'hello-word'
}
--------------
ref 使用方法
ref = {(input)=>{this.input = input}
const inputValue =this.input.value;
ref={ul => {this.ul = ul}}
console.log(this.ul.querySelectorAll('div').length);
-------------------
生命周期函数
// 避免子组件被重复调用, 只有参数发生改变才调用
shouldComponentUpdate(nextProps,nextState){
if(nextProps.content !== this.props.content){
return true;
}else{
return false;
}
}
---------------
yarn add axios
res
this.setState(()=>({
list:[...res.data]
}))
-----------------
原生的动画
/* .show{
opacity: 1;
transition: all 1s ease-in;
} */
/* .hide{
opacity: 0;
transition: all 1s ease-in;
} */
@keyframes hide-item {
0%{
opacity: 1;
color: red;
}
50%{
opacity: 0.5;
color: green;
}
100%{
opacity: 0;
color: blue;
}
}
@keyframes show-item {
0%{
opacity: 0;
color: blue;
}
50%{
opacity: 0.5;
color: green;
}
100%{
opacity: 1;
color: red;
}
}
.hide{
animation: hide-item 2s ease-in forwards;
}
.show{
animation: show-item 2s ease-in forwards;
}
----------CSSTransition 动画---------------
yarn add react-transition-group
import {CSSTransition} from 'react-transition-group'
<Fragment>
<CSSTransition
in={this.state.show}
timeout={1000}
classNames="fade"
// 隐藏时 卸载当前dom
unmountOnExit
// 动画结束的钩子函数
onEntered={el=>el.style.color="blue"}
// 第一次加载也有动画
appear={true}
>
<div> hello </div>
</CSSTransition>
<button onClick = {this.handleToggle}>toggle</button>
</Fragment>
css
.fade-enter, .fade-appear {
opacity: 0;
}
.fade-enter-active, .fade-appear-active{
opacity: 1;
transition: opacity 1s ease-in;
}
.fade-enter-done {
opacity: 1;
color: red;
}
.fade-exit{
opacity: 1;
}
.fade-exit-active{
opacity: 0;
transition: opacity 1s ease-in;
}
.fade-exit-done {
opacity: 0;
}
--------------TransitionGroup 多个item 动画效果------------------------------
render() {
return (
<Fragment>
<TransitionGroup>
{
this.state.list.map((item,index)=>{
return (
<CSSTransition timeout={1000} classNames="fade"
// 隐藏时 卸载当前dom
unmountOnExit
// 动画结束的钩子函数
onEntered={el=>el.style.color="blue"}
// 第一次加载也有动画
appear={true} key={item} >
<div >{item}</div>
</CSSTransition>
)
})
}
</TransitionGroup>
<button onClick = {this.handleAddItem}>toggle</button>
</Fragment>
)
}
handleAddItem(){
this.setState(prevState =>({
list: [...prevState.list,'item-' + (prevState.list.length + 1)]
}))
}
---------------------------
yarn add antd
-------------
yarn add redux
------------------
yarn add redux-thunk ->可以发送异步请求, 把方法放到 store 里面的actionCreators 里面 操作
1 安装引入 配置
import {createStore,applyMiddleware,compose } from 'redux'
import reducer from './reducer'
import thunk from 'redux-thunk'
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({trace:true}) || compose
const enhancer = composeEnhancers(applyMiddleware(thunk))
const strore = createStore(
reducer,
enhancer
);
export default strore
2 写方法 发送异步请求
export const initListAction = (data) =>{
return {
type: INIT_LIST_ACTION,
data
}
}
export const getTodoList = () => {
return (dispatch) => {
axios.get('/list.json').then((res)=>{
const data = res.data;
// 拿到结果 改变列表数据
const action = initListAction(data)
dispatch(action)
})
}
}
3 页面加载 触发请求操作
componentDidMount(){
const action = getTodoList()
store.dispatch(action)
}
---------------------
yarn add redux-saga
1 安装引入 配置
import {createStore,compose,applyMiddleware } from 'redux'
import reducer from './reducer'
import createSagaMiddleware from 'redux-saga'
import TodoSagas from './sagas'
const sagaMiddleware = createSagaMiddleware()
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({trace:true}) || compose
const enhancer = composeEnhancers(applyMiddleware(sagaMiddleware))
const strore = createStore(reducer,enhancer);
sagaMiddleware.run(TodoSagas)
export default strore
2 sagas.js
import {takeEvery,put} from 'redux-saga/effects'
import axios from 'axios'
import {
GET_INIT_LIST
} from './actionTypes'
import {
initListAction
} from './actionCreators'
function* getInitList(){
try {
const res = yield axios.get('/list.json')
const action = initListAction(res.data)
yield put(action);
}catch(e){
console.log('list 网络请求失败');
}
}
function* mySaga() {
yield takeEvery(GET_INIT_LIST, getInitList);
}
export default mySaga;
3 actionCreators.js
export const initListAction = (data) =>{
return {
type: INIT_LIST_ACTION,
data
}
}
export const getInitListAction = () => {
return {
type: GET_INIT_LIST
}
}
4 页面使用
componentDidMount(){
const action = getInitListAction()
store.dispatch(action)
}
----------------
yarn add react-redux
1
import { createStore } from 'redux'
import reducer from './reducer'
const store = createStore(
reducer,
window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__()
)
export default store
2
import React from 'react';
import ReactDOM from 'react-dom';
import TodoList from './TodoList';
import {Provider} from 'react-redux'
import store from './store';
const App = (
<Provider store={store}>
<TodoList/>
</Provider>
)
ReactDOM.render(App,document.getElementById('root'));
3
const defaultState = {
inputValue:'hello wrold',
list:[]
}
export default function reducre(state = defaultState,action){
if(action.type === 'change_input_value'){
const newState = JSON.parse(JSON.stringify(state))
newState.inputValue = action.value
return newState
}
return state
}
4
import React, { Component } from 'react'
import {connect} from 'react-redux'
class TodoList extends Component {
render() {
return (
<div>
<div>
<input value={this.props.inputValue} onChange={this.props.changeInputValue} />
<button>提交</button>
</div>
<ul>
<li>dill</li>
</ul>
</div>
)
}
}
const mapStateToProps = (state) =>{
return {
inputValue:state.inputValue,
list:state.list
}
}
const mapDispatchToProps = (dispatch) => {
return {
changeInputValue(e){
// console.log(e.target.value);
const action = {
type:"change_input_value",
value:e.target.value
}
dispatch(action)
}
}
}
export default connect(mapStateToProps,mapDispatchToProps)(TodoList)
------------------

浙公网安备 33010602011771号