首先,我读了这个问题React redux connect((无法包装定义为扩展React.component的类的组件但我仍然无法理解,因为连接是在某种更高级别上完成的,但我不理解那个阶段。
这是我目前的结构:
reduxStore.js
import { createStore } from "redux";
import rootReducer from "../reducers/index";
const store = createStore(rootReducer);
export default store;
action-types.js
export const RENDER_LAYOUT_ELEMENT = "REDER_LAYOUT_ELEMENT"
reduxActions.js
import {RENDER_LAYOUT_ELEMENT} from "../constants/action-types"
export function renderLayoutElement(payload){
return {type: RENDER_LAYOUT_ELEMENT}
};
reduxReducers.js
import {RENDER_LAYOUT_ELEMENT} from "../constants/action-types"
const initialState = {
renderedEl: {
heimdall: false,
skadi: false,
mercator: false
}
}
function renderedElReducer(state = initialState, action){
if(action.type === RENDER_LAYOUT_ELEMENT){
return Object.assign({},state,{
renderedEl: state.renderedEl.concat(action.payload)
})
}
return state
}
export default renderedElReducer;
现在我想要的是读取我拥有的组件中的renderedEl initialState。根据我的理解,我需要将该组件连接到商店,然后使用mapStateToProps读取全局状态(商店(
所以我去了我的组件,试图连接它,但我不知道在哪里做。
组件很大,但基本上我试图停止使用renderedEl的状态,从存储中读取它。当前正在使用的状态位于构造函数中,它应该被丢弃,因为它现在将从存储中读取。
在渲染中,样式的条件部分现在不会根据状态设置,而是根据存储设置我本来打算这么做的,但问题是,现在我还不知道如何将这个组件连接到商店。我看到的所有教程都与某种函数组件有关,而不是类组件
import React, { Component, useState } from "react";
import brand from "../images/valhallaNaranja.png";
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faArrowAltCircleLeft, faArrowAltCircleRight, faUser } from '@fortawesome/free-regular-svg-icons'
import { faColumns } from '@fortawesome/free-solid-svg-icons'
import './css/Sidebar.css'
import { isAdmin } from "../services/userCheck.js"
//select
const mapStateToProps = state => {
return { renderedEl: state.renderedEl }
}
export default class SideBar extends Component {
constructor(props) {
super(props);
this.state = {
retracted: this.props.retracted,
isAdmin: false,
isHovering: false,
//THIS STATE IS WHAT IM TRYING TO REPLACE BY READING FROM THE STORE
renderedEl: {
heimdall: false,
skadi: false,
mercator: false
}
}
this.hoverTrue = this.hoverTrue.bind(this);
this.hoverFalse = this.hoverFalse.bind(this);
}
componentDidMount() {
if (isAdmin()) {
this.setState({
isAdmin: true
})
}
}
componentDidUpdate() {
if (this.state.retracted != this.props.retracted) {
this.setState({
retracted: this.props.retracted
})
}
}
renderEl = (el) => {
var elementName = el.target.getAttribute('id');
var renderedElements = this.state.renderedEl;
for (let key in renderedElements) {
if (key == elementName) {
renderedElements[key] = true
}
}
this.setState({
renderEl: renderedElements
})
}
hoverTrue() {
this.setState({
isHovering: true
})
}
hoverFalse() {
this.setState({
isHovering: false
})
}
render() {
let navbar_brand = this.state.retracted ? "navbar-brand-retracted" : "navbar-brand";
let img_redie = this.state.retracted ? "img-redie-retracted" : "img-redie";
let home_icon = this.state.retracted ? "divicon homeicon-retracted" : "divicon homeicon";
let register_icon = this.state.retracted ? "divicon divicon2 registericon-retracted" : "divicon divicon2 registericon";
let expand_icon = this.state.retracted ? "divicon-no-hover divicon2 expandicon-retracted" : "divicon divicon2 expandicon";
//THOSE STATES WILL BE READ NOW FROM THE STORE
let skadiRendered = this.state.renderedEl.skadi ? "bubbletext bubbletext-rendered" : "bubbletext";
let heimdallRendered = this.state.renderedEl.heimdall ? "bubbletext bubbletext-rendered" : "bubbletext";
let mercatorRendered = this.state.renderedEl.mercator ? "bubbletext bubbletext-rendered" : "bubbletext";
let layoutAppVisualSelector = this.props.history.location.pathname == "/layout" ? "divicon divicon2 expandicon divicon-layout" : "divicon divicon2 expandicon";
return (
<div id="sidebar" className={this.state.retracted ? 'sidebar-retracted' : 'sidebar-expanded'}>
<div /*routerLink=""*/ className={navbar_brand}>
<img alt="Reddie" src={brand} width="60" height="60" className={img_redie} />
</div>
<ul className="nav nav3 navbar-nav">
<li>
{/* Home icon */}
<div className={home_icon} onClick={() => this.props.history.push('/')}>
<svg className="svgicon-sidebar" viewBox="0 0 14 14" >
<path d="M13.9 5.7L7.2.8c-.1-.1-.3-.1-.4 0L.1 5.7c-.1.1-.1.3 0 .5s.3.2.5.1L7 1.6l6.4 4.7c.1 0 .1.1.2.1s.2-.1.3-.1c.1-.3.1-.5 0-.6" />
<path d="M12.1 6.4c-.2 0-.4.2-.4.4v5.8H8.8V9.4c0-1-.8-1.8-1.8-1.8s-1.8.8-1.8 1.8v3.2H2.3V6.7c0-.2-.2-.4-.4-.4s-.4.2-.4.4v6.2c0 .2.2.4.4.4h3.6c.2 0 .3-.1.4-.3V9.4c0-.6.5-1.1 1.1-1.1.6 0 1.1.5 1.1 1.1v3.5c0 .2.2.3.4.3h3.6c.2 0 .4-.2.4-.4V6.7c0-.2-.2-.3-.4-.3" />
</svg>
</div>
</li>
{this.state.isAdmin ? <li>
<div className={register_icon} onClick={() => this.props.history.push('/admin')}>
<FontAwesomeIcon className="registerIcon" icon={faUser} />
</div>
</li> : null}
{(this.props.history.location.pathname != "/layout") && (this.props.history.location.pathname != "/skadi") && (this.props.history.location.pathname != "/heimdall") && (this.props.history.location.pathname != "/mercator") ? null : <li>
<div className={layoutAppVisualSelector} onMouseEnter={this.hoverTrue}
onMouseLeave={this.hoverFalse} >
<FontAwesomeIcon className="registerIcon" icon={faColumns} onClick={() => this.props.history.push({ pathname: '/layout', state: { comeFrom: this.props.history.location.pathname } })} />
{(this.state.isHovering && this.props.history.location.pathname == "/layout") ? <div className="speech-bubble" onMouseLeave={this.hoverFalse}
onMouseEnter={this.hoverTrue}>
<span id="heimdall" className={heimdallRendered} onClick={(el) => this.renderEl(el)}>Heimdall</span> <br /> <span className={skadiRendered} id="skadi" onClick={(el) => this.renderEl(el)}>Skadi</span> <br /> <span id="mercator" className={mercatorRendered} onClick={(el) => this.renderEl(el)}>Mercator</span>
</div> : null}
</div>
</li>}
{(this.state.retracted) || ((this.props.history.location.pathname == "/") || (this.props.history.location.pathname == "/register")) || (this.props.history.location.pathname == "/admin") || (this.props.history.location.pathname == "/layout") ? null : <li>
<div className="divicon divicon2 expandicon " onClick={this.props.retract}>
<FontAwesomeIcon className="registerIcon" icon={faArrowAltCircleLeft} />
</div>
</li>}
</ul>
{this.state.retracted ? <div className="expandicon-retracted-container"> <FontAwesomeIcon className="expandicon-retracted" icon={faArrowAltCircleRight} onClick={this.props.unretract} /> </div> : null}
</div>
)
}
}
我该如何连接该组件?
首先,您需要用reduxProvider
包装根组件(最推荐的index.js或App.js…(
import { Provider } from 'react-redux'
<Provider store={store}>
<App />
</Provider>
这样之后,将为该下的所有零件提供存储,并且可以像一样进行connect
编辑
import { connect } from 'react-redux'
const mapStateToProps = state => {
return { renderedEl: state.renderedEl }
}
class SideBar extends Component {
componentDidMount() {
console.log(this.props.renderedEL)
}
}
export default connect(mapStateToProps)(SideBar)
至于你的行动,dispatch
对减速器的行动
export function renderLayoutElement(payload){
return dispatch => dispatch({type: RENDER_LAYOUT_ELEMENT})
}
仅为测试目的执行export class SideBar [...]
,但执行export default connect(mapStateToProps)(SideBar)
,它将组件连接到redux
状态并为道具分配精简状态。
编辑:您要查找的文档在这里。