[React]--组件封装、父子组件传值、redux持久化保存公共数据、类v-model实现

601 阅读2分钟

这是我参与8月更文挑战的第9天,活动详情查看:8月更文挑战

一、 react中父子组件传值

1. 一个搜素组件利用父子组件传值实现隐藏显示功能

1. 传递样式可以通过display:none,来隐藏搜索子组件,子组件通过props来接受

 // 父组件中
 this.state = {
            searchComponentStyle: {
                display: 'none'
            }
        }
<SearchComponent pageStyle={this.state.searchComponentStyle}></SearchComponent>

// 子组件中
 <div id='component-search' style={this.props.pageStyle}>

2. 子组件通过调用父组件的方法来实现传值隐藏功能

// 子组件中
 <div className="close-btn" onClick={this.props.changeStyle.bind(this,'none')}></div>
// 父组件中
 // 显示隐藏搜索组件
    changeSearchComponentShow(style ='block') {
    
        this.setState({
            searchComponentStyle: {
                display: style
            }
        })
    }
  <div className="search-container" onClick={ this.changeSearchComponentShow.bind(this,'block')}>
                        <div className="search-btn"></div>
                        <div className="search-holder">请输入宝贝名称</div>
                    </div>   

Kapture 2021-08-21 at 12.15.47.gif

二、 在react中使用ant-mobile

1. 安装npm install antd-mobile --save

2. 按需引入安装: npm install babel-plugin-import --save-dev

2.1 配置package.json中的babel

"babel": {
    "presets": [
      "react-app"
    ],
    "plugins": [
      [
        "import",
        {
          "libraryName": "antd-mobile",
          "style": "css"
        }
      ]
    ]
  },

2.2 使用搜索组件删除历史记录的对话框

import  {Modal} from 'antd-mobile'
<div className="delete-icon"  onClick={this.openConfirmDeleteDialog.bind(this)}></div>
 // 打开删除确认弹框
    openConfirmDeleteDialog() {
        Modal.alert('确认要删除吗?','',[
            {
                text:'取消',
                onPress: () => {}
            },{
                text:'确认',
                onPress: () => {}
            },
        ])
    }

Kapture 2021-08-21 at 12.22.53.gif

分模块使用redux

  1. 回顾在vuex的状态管理: 无非是actions、mutation、state、getters这些,分模块加了个modules而已
  2. 运用在readux中的状态管理: 少了state,getter,而用action和reducers代理
  3. 运用redux的数据流
// 1. 在src下建立actions和reducers两个目录,分模块方便后期公共数据的管理

截屏2021-08-21 下午4.14.32.png

最小粒度的redux分模块demo

// 1. actions
// historyKeywords.js
function addHistoryKeyword(data) {
    console.log(data,'actions中来数据....')
    return {
        type: 'addHistoryKeyword',
        data
    }
}

export  {
    addHistoryKeyword
}
// index.js
import * as historyKeywords from "./historyKeywords";

export default {
    historyKeywords
}

// 2. reducers
// historyKeywords.js
let historyKeywords = localStorage['historyKeywords'] ? JSON.parse(localStorage['historyKeywords']) : []

function historyKeywordsReducer(state ={historyKeywords},action) {
    switch (action.type) {
        case 'addHistoryKeyword':
            console.log(state,'原来的state')
            console.log(action, 'reducers中来数据...')
            console.log(Object.assign({},state,action),'后来的数据')
            return   Object.assign({},state,action)
        default:
            return  state
    }
}

export default historyKeywordsReducer

// index.js
import {combineReducers} from "redux";
import historyKeywords from "./historyKeywords";

export default combineReducers({
    hkReducers:historyKeywords
})

// 3. 入口文件的index.js
/*eslint-disable*/
import 'babel-polyfill';
import 'url-search-params-polyfill';
import React from 'react';
import ReactDOM from 'react-dom';
import RouterComponent from './router';
import * as serviceWorker from './serviceWorker';
import "./assets/js/libs/zepto.js";
import "./assets/css/common/public.css";
import 'whatwg-fetch'
import {Provider} from "react-redux";
import {createStore} from "redux";
import Reducers from './reducers'

let store = createStore(Reducers)


class Index extends React.Component {
    render() {
        return (
            <React.Fragment>
                <Provider store={store}>
                    <RouterComponent />
                </Provider>
            </React.Fragment>
        )
    }
}

ReactDOM.render(<Index />, document.getElementById('root'));

serviceWorker.unregister();

// 4. 在业务组件中使用
// search.js 组件中
import {connect} from "react-redux";
import actions from "../../actions";

constructor(props) {
this.historyKeywords = props.state.hkReducers.historyKeywords
}
 
 // 删除确认
onPress: () => {
                    this.setState({
                        historyKeywordsShow: false
                    })
                   this.historyKeywords = []
                    this.props.dispatch(actions.historyKeywords.addHistoryKeyword({
                        historyKeywords: this.historyKeywords
                    }))
                    localStorage.removeItem('historyKeywords')
                }
  
  // 添加
  addHistoryKeywords() {
        if(!this.state.searchKeyword){
            return
        }
        let index  = this.historyKeywords.findIndex(v => v === this.state.searchKeyword)
        if(index !== -1) {
            this.historyKeywords.splice(index,1)
        }
        this.historyKeywords.unshift(this.state.searchKeyword)
        this.props.dispatch(actions.historyKeywords.addHistoryKeyword({historyKeywords:this.historyKeywords }))
        localStorage.setItem('historyKeywords',JSON.stringify(this.historyKeywords))
        if (!this.state.historyKeywordsShow) {
            this.setState({
                historyKeywordsShow: true
            })
        }
    }

export default connect(state => {
    console.log(state,'search中的state....')
    return {
        state:state
    }
})(SearchComponent)

最后补充下react没有像vue中的v-model我们自己实现

 <input type="text"  onChange={event => {this.setState({searchKeyword: event.target.value.trim()})}} />

Kapture 2021-08-21 at 16.25.45.gif