react-笔记


Fragment 占位符标签 使用方法

class => className
className="input"

{/* 注释内容 */}
// 注释内容

dangerouslySetInnerHTML={{__html:item}} 可以解析 html 标签

  • onClick={()=>this.handleItemDelete(index)}
    dangerouslySetInnerHTML={{__html:item}}>
  • htmlFor 点击扩大区域


    代码优化 性能优化
    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 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 (

    {content}

    )
    }

    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'

    in={this.state.show}
    timeout={1000}
    classNames="fade"
    // 隐藏时 卸载当前dom
    unmountOnExit
    // 动画结束的钩子函数
    onEntered={el=>el.style.color="blue"}
    // 第一次加载也有动画
    appear={true}
    >

    hello



    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 (


    {
    this.state.list.map((item,index)=>{
    return (
    // 隐藏时 卸载当前dom
    unmountOnExit
    // 动画结束的钩子函数
    onEntered={el=>el.style.color="blue"}
    // 第一次加载也有动画
    appear={true} key={item} >

    {item}


    )
    })
    }




    )
    }

    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

    import React from 'react';
    import ReactDOM from 'react-dom';
    import TodoList from './TodoList';
    import {Provider} from 'react-redux'
    import store from './store';

    const App = (



    )

    ReactDOM.render(App,document.getElementById('root'));

    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
    }

    import React, { Component } from 'react'
    import {connect} from 'react-redux'

    class TodoList extends Component {

    render() {
    return (






    • dill



    )
    }

    }

    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)


    ------------------