因此,在我不受控制的PossibleMatches组件中,我从React的工作方式知道,初始渲染阶段将发生空的prop值(如果这些prop值依赖于外部应用程序状态(mapStateToProps)),无论我是否有componentDidMount生命周期方法或构造函数设置。为此,我在componentDidMount中设置了一个promise,这样当我调度prop函数[defaultPieces,arrangePieces]时,我可以让UI渲染一个ActivityIndicator来指示当前正在获取的东西。问题是,当我从promise的成功阶段调用mapStateToProps时,我似乎无法获得mapStateToProps函数来理解状态。这是:
class PossibleMatches extends Component {
constructor(props){
super(props);
}
componentDidMount(props){
return new Promise((resolve, reject) => {
let state;
let {defaultPieces, arrangePieces, isFetching} = this.props;
let makeClothesAppear = function(){
defaultPieces();
arrangePieces();
isFetching = true;
}
resolve(makeClothesAppear());
}).then(function(state){
mapStateToProps(state);
this.props.isFetched = true
this.props.isFetching = false;
}).catch((error) => {
console.log('FetchClothesError: ', error);
})
}
}
用户界面如何决定要显示的内容:
renderDecision(){
const {UpperComponents, LowerComponents} = this.props;
const {currentUpperComponent, currentLowerComponent} = this.state.currentComponent.whichPiece;
const {LowerComponentEnabled, UpperComponentEnabled} = this.state;
if (this.props.isFetching){
return (<div className='activityLoader'>
<ActivityIndicator number={3} duration={200} activeColor="#fff" borderWidth={2} borderColor="50%" diameter={20}/>
</div>);
} else if (this.props.isFetched){
return (<div className = "PossibleMatches_Container">
<i className = 'captureOutfit' onClick = {this.snapshotMatch}></i>
{UpperComponents.map((component) => {
return (<UpperComponent key={component.createdAt} id={component.id}
switchComponent={this.switchFocus}
setCurrentPiece = {this.setNewPiece}
evaluatePiece={this.isOppositeComponentSuggested}
image={component.image}
toggleToPiece = {(LowerComponentEnabled) => {if (LowerComponentEnabled === false){this.setState({LowerComponentEnabled: true})}else{return;} this.setState({currentLowerComponent: this.props.suggestedBottoms[0]})}}
isLowerComponentEnabled={LowerComponentEnabled}
ref={this.residingUpperComponent}
className = {this.state.currentComponent.whichPiece.whichType === 'match' ? 'PossibleMatches_Container' : this.state.currentComponent.whichPiece.whichType === 'bottom' ? 'standalonePiece' : 'standalonePiece'}/>)
})
}
{LowerComponents.map((component) => {
return (<LowerComponent key={component.createdAt} id={component.id}
setCurrentPiece = {this.setNewPiece}
evaluatePiece={this.isOppositeComponentSuggested}
image={component.image}
toggleToPiece={(UpperComponentEnabled) => {if (UpperComponentEnabled === false){this.setState({UpperComponentEnabled: true})}else{return;} this.setState({currentUpperComponent: this.props.suggestedTops[0]})}}
switchComponent={this.switchFocus}
isUpperComponentEnabled={UpperComponentEnabled}
ref={this.residingLowerComponent}
className = {this.state.currentComponent.whichPiece.whichType === 'match' ? 'PossibleMatches_Container' : this.state.currentComponent.whichPiece.whichType === 'bottom' ? 'standalonePiece' : 'standalonePiece'}/>)
})
}
</div>)
}
}
render(){
return(
<div className = 'GorClothingContainer'>
{/*<Wardrobe upperComponent={this.state.currentComponent.whichPiece.currentUpperComponent} lowerComponent={this.state.currentComponent.whichPiece.currentLowerComponent} enableCapture={(snapshot) => this.snapshotMatch = snapshot} />*/}
{this.renderDecision()}
</div>
);
}
我的PossibleMatches Reducer
import {INITIAL_PIECES, GET_ANCILLARY_PIECES, ORGANIZE_PIECES, SET_CONTEMPLATED_PIECE} from '../actions/types';
const initialState = {
UpperComponents: [],
LowerComponents: [],
contemplated_piece: null,
extraTops: [],
extraBottoms: [],
standaloneTops: [],
standaloneBottoms: [],
suggestedTops: [],
suggestedBottoms: []
}
export default function(state = initialState, action){
switch(action.type){
case INITIAL_PIECES:
return Object.assign({}, state, {contemplated_piece: action.payload.contemplated_piece},
{extraTops: action.payload.extra_tops},
{extraBottoms: action.payload.extra_bottoms},
{standaloneTops: action.payload.standalone_tops},
{standaloneBottoms: action.payload.standalone_bottoms},
{suggestedTops: action.payload.suggested_tops},
{suggestedBottoms: action.payload.suggested_bottoms})
case GET_ANCILLARY_PIECES:
return Object.assign({}, state, {extraTops: action.payload.extra_tops},
{extraBottoms: action.payload.extra_bottoms},
{standaloneTops: action.payload.standalone_tops},
{standaloneBottoms: action.payload.standalone_bottoms},
{suggestedTops: action.payload.suggested_tops},
{suggestedBottoms: action.payload.suggested_bottoms})
case ORGANIZE_PIECES:
return Object.assign({}, state, {UpperComponents: action.payload.UpperComponents},
{LowerComponents: action.payload.LowerComponents})
case SET_CONTEMPLATED_PIECE:
return Object.assign({}, state, {contemplated_piece: action.payload.contemplated_piece})
default:
return state;
}
}
我的combineReducers细分
import {combineReducers} from 'redux';
const allReducers = combineReducers({
Playlist: PlaylistReducer,
eventOptions: eventTicketReducer,
possibleMatches: PossibleMatchesReducer,
Intro: combineForms({
basicUserInfo: BasicUserInfoState,
GenderInfo: GenderInfoState,
ContactInfo: ContactInfoState
}, 'Intro'),
routing: routerReducer,
form: formReducer
});
道具价值观
PossibleMatches.defaultProps = {
isFetching: true,
isFetched: false
}
我的mapStateToProps功能
function mapStateToProps(state){
return {UpperComponents: state.possibleMatches.UpperComponents,
LowerComponents: state.possibleMatches.LowerComponents,
contemplatedPiece: state.possibleMatches.contemplated_piece,
extraTops: state.possibleMatches.extraTops,
extraBottoms: state.possibleMatches.extraBottoms,
standaloneTops: state.possibleMatches.standaloneTops,
standaloneBottoms: state.possibleMatches.standaloneBottoms,
suggestedTops: state.possibleMatches.suggestedTops,
suggestedBottoms: state.possibleMatches.suggestedBottoms}
}
function mapDispatchToProps(dispatch){
return {
defaultPieces: () => {
dispatch(defaultPieces())
},
arrangePieces: () => {
dispatch(arrangePieces())
},
getCorrespondingPieces: () => {
dispatch(getCorrespondingPieces())
},
setEvaluatedPiece: () => {
dispatch(setEvaluatedPiece())
}
}
}
export default connect(mapStateToProps, mapDispatchToProps)(PossibleMatches)
我的问题是:我实施承诺的方式究竟出了什么问题。正确设置reducers和redux操作(我知道因为我已经从redux动作文件中将获取的项目记录到控制台),我如何正确填充mapStateToProps中的prop值。目前错误是:
我正在使用React 16.4.0
答案 0 :(得分:1)
一个简单的redux用例如下所示
possibleMatches.jsx(组件文件)
@ECHO OFF
:parameterLoop
IF /I "%1"=="/install" GOTO install
IF /I "%1"=="/uninstall" GOTO uninstall
IF /I "%1"=="/repair" GOTO repair
IF /I "%1"=="" (
ECHO.
ECHO Please use the following commands to proceed:
ECHO.
ECHO Use /INSTALL to setup the software
ECHO.
ECHO Use /UNINSTALL to remove the software
ECHO.
ECHO Use /REPAIR to repair the software
ECHO.
GOTO end
)
:install
TASKKILL /F /IM vpnui* /T
TASKKILL /F /IM DartOffline* /T
MSIEXEC /I "anyconnect-win-XXX-core-vpn-predeploy-k9.msi" /QN /NORESTART
MSIEXEC /I "anyconnect-win-XXX-dart-predeploy-k9.msi" /QN /NORESTART
MSIEXEC /I "anyconnect-win-XXX-posture-predeploy-k9.msi" /QN /NORESTART
COPY /Y "production.xml" "%ProgramData%\Cisco\Cisco AnyConnect Secure Mobility Client\Profile\production.xml"
GOTO end
:uninstall
TASKKILL /F /IM vpnui* /T
TASKKILL /F /IM DartOffline* /T
DEL /F /S /Q "%ProgramData%\Cisco\Cisco AnyConnect Secure Mobility Client\Profile\production.xml"
MSIEXEC /X "anyconnect-win-XXX-core-vpn-predeploy-k9.msi" /QN /NORESTART
MSIEXEC /X "anyconnect-win-XXX-dart-predeploy-k9.msi" /QN /NORESTART
MSIEXEC /X "anyconnect-win-XXX-posture-predeploy-k9.msi" /QN /NORESTART
RMDIR /S /Q "%ProgramData%\Cisco\Cisco AnyConnect Secure Mobility Client"
GOTO end
:repair
TASKKILL /F /IM vpnui* /T
TASKKILL /F /IM DartOffline* /T
DEL /F /S /Q "%ProgramData%\Cisco\Cisco AnyConnect Secure Mobility Client\Profile\production.xml"
MSIEXEC /X "anyconnect-win-XXX-core-vpn-predeploy-k9.msi" /QN /NORESTART
MSIEXEC /X "anyconnect-win-XXX-dart-predeploy-k9.msi" /QN /NORESTART
MSIEXEC /X "anyconnect-win-XXX-posture-predeploy-k9.msi" /QN /NORESTART
RMDIR /S /Q "%ProgramData%\Cisco\Cisco AnyConnect Secure Mobility Client"
MSIEXEC /I "anyconnect-win-XXX-core-vpn-predeploy-k9.msi" /QN /NORESTART
MSIEXEC /I "anyconnect-win-XXX-dart-predeploy-k9.msi" /QN /NORESTART
MSIEXEC /I "anyconnect-win-XXX-posture-predeploy-k9.msi" /QN /NORESTART
COPY /Y "production.xml" "%ProgramData%\Cisco\Cisco AnyConnect Secure Mobility Client\Profile\production.xml"
GOTO end
:end
EXIT /B
REM Src https://stackoverflow.com/questions/8179425/adding-switch-in-batch
actions.js(动作创建者文件) 使用此操作将任何数据更新为redux
class PossibleMatches extends React.Component {
state = {
isFetching: false
}
componentDidMount() {
this.setState({isFetching: true})
fetchingSomethingFromServer()
.then(resp => {
this.setState({isFetching: false})
this.props.UpdateRedux(resp)
});
}
render() {
const { isFetching } = this.state;
const { data } = this.props;
return (
isFetching ? <div>loading...</div> : <div>{data}</div>
)
}
}
export default connect(state => ({ data: state.possibleMatches.data }), {UpdateRedux})
reducers.js 这是包含redux状态的文件
export const UpdateRedux = (data) => {type: 'UPDATE_REDUX', payload: data}
在您的联合收割机中导入此缩减器并按如下方式分配
const defaultState = {
data: null
}
export default (state = defaultState, action) => {
switch(action.type) {
case 'UPDATE_REDUX':
return {data: action.payload};
default:
return state
}
}