React Redux Reducer从状态获取数据吗?

时间:2018-08-16 19:08:20

标签: javascript reactjs redux

尝试弄乱react和redux以从API提取文件列表。

在react react开发工具中查看时,我可以在那里看到我的数据,但它并未呈现。

actions.js

export const requestFiles  = ({
    type: REQUEST_FILES,
});

export const receiveFiles = (json) => ({
    type: RECEIVE_FILES,
    files: json,
    receivedAt: Date.now()
});


export const fetchFiles = (dispatch) => {
    dispatch(requestFiles);
    return fetch('/api/files')
        .then(response => response.json())
        .then(json => dispatch(receiveFiles(json)))
};

该操作从JSON获取数据

enter image description here

reducer.js

const files = (state = {
    isFetching: false,
    items: []
}, action) => {
    switch (action.type) {
        case REQUEST_FILES:
            return {
                ...state,
                isFetching: true,
            };
        case RECEIVE_FILES:
            return {
                ...state,
                isFetching: false,
                items: action.files,
                lastUpdated: action.receivedAt
            };
        default:
            return state
    }
};

const filesUploaded = (state = { }, action) => {
    switch (action.type) {
        case RECEIVE_FILES:
        case REQUEST_FILES:
            return {
                ...state,
                items: files(state[action], action)
            };
        default:
            return state
    }
};

const rootReducer = combineReducers({
    filesUploaded
});

export default rootReducer

App.js

class App extends Component {
    static propTypes = {
        files: PropTypes.array.isRequired,
        isFetching: PropTypes.bool.isRequired,
        dispatch: PropTypes.func.isRequired
    };

    componentDidMount() {
        const {dispatch} = this.props;
        dispatch(fetchFiles);
    }

    handleChange = nextSubreddit => {
    };

    render() {
        const {files, isFetching} = this.props;
        const isEmpty = files.length === 0;
        console.log(`Files is empty ${isEmpty}`);
        return (
            <div>
                <h1>Uploadr</h1>
                {isEmpty
                    ? (isFetching ? <h2>Loading...</h2> : <h2>No files.</h2>)
                    : <div style={{opacity: isFetching ? 0.5 : 1}}>
                        <Files files={files}/>
                    </div>
                }
            </div>
        )
    }
}

const mapStateToProps = state => {
    const {uploadedFiles} = state;
    const {isFetching, items: files} = uploadedFiles
        || {isFetching: true, items: []};

    console.log(files);

    return {
        files,
        isFetching,
    }
};

enter image description here

该操作中正在接收的数据,但是我不确定是否正在存储它,或者问题是否从redux存储中访问。

如上面的屏幕快照所示,App组件上的files属性仍然为零。

有什么想法吗?

2 个答案:

答案 0 :(得分:1)

您的filesUploaded减速器没有任何意义。我不确定filesUploaded应该做什么。您的files减速器看起来像普通的减速器。看来您可以删除filesUploaded,一切都会好起来的。

尤其是filesUploaded正在呼叫files(state[action], action)action是一个对象。 state[SOME_OBJECT]应该是什么?因为它被解析为state['[object Object]'],所以它肯定是未定义的,永远也不会被定义。

您的files减速器还具有一个从未使用过的items参数。减速器应仅具有两个参数:状态和动作。删除items参数。

您的mapStateToProps正在寻找state.uploadedFiles,但您的减速器称为filesUploaded。应该是state.filesUploaded(或者如果您用files减速器替换,只需state.files)。

mapStateToProps不需要|| {isFetching: true, items: []},因为您在files减速器上具有初始状态。

答案 1 :(得分:1)

删除您的<div> <input type="checkbox" id="isevent" runat="server" class="rcorners" onclick="javascript:f1()" />&nbsp;Staffed Event? </div> <div> <input type="text" id="eventname" class="rcorners input" runat="server" placeholder="Event Name" style="display:none;" maxlength="128" /> </div> <div> <input type="text" id="campaign" runat="server" class="rcorners input" placeholder="Campaign" maxlength="64" style="display:none;" /> </div> <script type="text/javascript"> function f1() { var mycheck = document.getElementById("isevent").checked; var myevent = document.getElementById("eventname"); var mycampaign = document.getElementById("campaign"); if (mycheck === true) { myevent.style.display = 'block'; mycampaign.style.display = 'block'; alert("Myevent's visibility is " + myevent.style.display); } else { myevent.style.display = 'none'; mycampaign.style.display = 'none'; } } </script> 减速器。不用了相反,只需使用filesUploaded减速器:

files

请注意,您感兴趣的状态片将称为const rootReducer = combineReducers({ files, }); 。将您的files函数更改为此:

mapStateToProps

您可以在这里看到,我们获取了const mapStateToProps = state => { const {isFetching, items: files} = state.files console.log(files); return { files, isFetching, } }; 状态片,并将其传递给您的组件。