【问题标题】:React with Redux: returns incorrect state object与 Redux 反应:返回不正确的状态对象
【发布时间】:2018-05-10 11:02:39
【问题描述】:

我有 React with Redux 和 Electron 项目。我尝试将当前屏幕 id 保存到 redux 并在下一个屏幕上获取保存状态。问题是,当我使用 getSettings 时,返回值应该是我保存的状态:

Object{settings: Object}

但是是动作的对象:

Object{type: "GET_SETTINGS", payload: ""}

当我将控制台日志放入 reducer_settings.js 时,它会显示正确的状态。所以它似乎与绑定 getSettings 方法有关。感谢您的帮助

容器/screen_picker.js:

import React, {Component} from 'react';
import Navigation from "../components/navigation";
const {desktopCapturer, ipcRenderer} = require('electron');
import {connect} from 'react-redux';
const domify = require('domify')
import App from '../components/app'
import {bindActionCreators} from 'redux';
import {setSettings, getSettings} from "../actions/index";

class ScreenPicker extends App {
    constructor(){
        super();
        this.showPicker();
    }

    showPicker(){
        ipcRenderer.send('show-picker', { types: ['screen'] });

        ipcRenderer.on('get-sources', (event, options) => {
            desktopCapturer.getSources(options, (error, sources) => {
                if (error) throw error
                let sourcesList = document.querySelector('.capturer-list')
                for (let source of sources) {
                    let thumb = source.thumbnail.toDataURL()
                    if (!thumb) continue
                    let title = source.name.slice(0, 20)
                    let item = `<li><a href="#"><img src="${thumb}"><span>${title}</span></a></li>`
                    sourcesList.appendChild(domify(item))
                }
                let links = sourcesList.querySelectorAll('a')
                for (let i = 0; i < links.length; ++i) {
                    let closure = (i) => {
                        return (e) => {
                            e.preventDefault()
                            // ipcRenderer.send('source-id-selected', sources[i].id)
                            // sourcesList.innerHTML = ''

                            this.props.setSettings({
                               screenId: sources[i].id
                           });
                        }
                    }
                    links[i].onclick = closure(i)
                }
            })
        })
    }

    render() {
        return (
            <div className="window-wrapper">
                <div className="main-content">
                    <div className="capturer-container dn">
                        <div className="cr">
                            <p className="mbl">Select the window you want to share:</p>
                            <ul className="capturer-list"></ul>
                        </div>
                    </div>
                </div>
                <Navigation nextRouteUrl="/camera-test" backRouteUrl="/"  />
            </div>
        )
    }

}

function mapStateToProps(state){
    return {
        settings: state.settings
    }
}

function mapDispatchToProps(dispatch){
    return bindActionCreators({setSettings, getSettings}, dispatch);
}

export default connect(mapStateToProps, mapDispatchToProps)(ScreenPicker);

容器/camera_test.js

const {ipcRenderer} = require('electron');
import React, {Component} from 'react';
import Navigation from "../components/navigation";
import {connect} from 'react-redux';
import App from '../components/app'
import {bindActionCreators} from 'redux';
import {getSettings} from "../actions/index";

class CameraTest extends App {
    constructor(){
        super();
    }

    componentDidMount() {
        console.log("settings in camera test start");
        console.log(this.props.getSettings());
        console.log("settings in camera test end");
        ipcRenderer.send('stepWindow:create', { });
    }

    render() {
        return (
            <div className="window-wrapper">
                <div className="main-content">
                    CameraTest div
                </div>
                <Navigation nextRouteUrl="/camera-test" backRouteUrl="/screen-picker"  />
            </div>
        )
    }

}

function mapStateToProps(state){
    return {
        settings: state.settings
    }
}

function mapDispatchToProps(dispatch){
    return bindActionCreators({getSettings}, dispatch);
}

export default connect(mapStateToProps, mapDispatchToProps)(CameraTest);

reducers/reducer_settings.js:

import {GET_SETTINGS, SET_SETTINGS} from "../actions/index";

export default function (state = {},action) {
    let newState;

    switch (action.type){
        case GET_SETTINGS:
            console.log("reducer GET_SETTINGS");

            console.log(state);
            return state;
        case SET_SETTINGS:
            newState = { ...state, ["settings"]: action.payload };
            console.log("Start newstate");
            console.log(newState);
            console.log("End newstate");
            return newState;

        default:
            return state
    }
}

actions/index.js

export const SET_SETTINGS = 'SET_SETTINGS';
export const GET_SETTINGS = 'GET_SETTINGS';

export function setSettings(values, callback){
    return {
        type: SET_SETTINGS,
        payload: values
    }
}

export function getSettings(){
    console.log("actions#getSettings");

    return {
        type: GET_SETTINGS,
        payload: ""
    }
}

【问题讨论】:

    标签: reactjs redux electron


    【解决方案1】:

    您不需要 getSetting 操作创建器。

    在您的组件中确实 mount 访问了这样的设置。

    componentDidMount() {
        console.log("settings in camera test start");
         const { settings} = this.props;
        console.log(settings);
        console.log("settings in camera test end");
        ipcRenderer.send('stepWindow:create', { });
    }
    

    假设您的对象称为设置。通常,该对象被赋予您在减速器中导出的名称。所以如果你在 props 中看不到一个名为 settings 的对象,你需要给你的 reducer 函数一个名字

    export default function settings (state = {},action) {
    let newState;
    
    switch (action.type){
        case GET_SETTINGS:
            console.log("reducer GET_SETTINGS");
    
            console.log(state);
            return state;
        case SET_SETTINGS:
            newState = { ...state, ["settings"]: action.payload };
            console.log("Start newstate");
            console.log(newState);
            console.log("End newstate");
            return newState;
    
        default:
            return state
    }
    }
    

    编辑:它给出对象名称的 mapStateToProps 是 props。

    【讨论】:

    • 感谢您的快速响应,它解决了我的问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-04-19
    • 2019-12-29
    • 2020-07-16
    • 1970-01-01
    • 2017-12-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多