调用useEffect()时,未触发Redux操作(从数据库获取)

时间:2020-07-16 13:51:38

标签: redux react-redux use-effect

我正在尝试建立一个电子商务网站来学习Redux。

此刻,我正在尝试在组件安装时获取类别。由于我使用的是功能组件,因此我知道可以通过调用useEffect()方法来实现。

此外,我正在使用json-server作为REST Api。

我很确定我已经设法组成了增强器以传递到商店(开发工具和thunk),创建了动作,reducer等。

我的问题是,在安装组件时,动作不会触发。

在介绍中间件和获取请求之前,一切正常。还要考虑到获取请求是成功的。

这是其中的代码。

'src / index.js'

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
import { createStore, applyMiddleware, compose } from 'redux'
import { Provider } from 'react-redux'
import rootReducer from './reducers'
import thunk from 'redux-thunk'

const composedEnhancers = compose(applyMiddleware(thunk), window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__())

const store = createStore(
  rootReducer, /* preloadedState, */
  composedEnhancers
);

ReactDOM.render(
  <Provider store={store}>
    <React.StrictMode>
      <App />
    </React.StrictMode>
  </Provider>,
  document.getElementById('root')
);

// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.

serviceWorker.unregister();

“ actions / index.js”中的操作类型:

export const FETCH_CATEGORIES = 'FETCH_CATEGORIES'

“ actions / index.js”中的动作创建者:

export const fetchCategories = () => (dispatch) => {
    fetch("http://localhost:7000/categories")
        .then(response => response.json())
        .then(categories => {
            return {
                type: FETCH_CATEGORIES,
                payload: categories
            }
        })

}

'reducers / index.js'

import * as actions from './../actions'

const initState = {
    categories: [],
    currentCategory: 'any',
    toggler: 'hidden'
}

const rootReducer = (state = initState, action) => {
    switch (action.type) {
        case actions.SELECT_CATEGORY:
            return { ...state, currentCategory: action.payload.value }
        case actions.FETCH_CATEGORIES:
            return { ...state, categories: action.payload }
        case actions.TOGGLE:
            return { ...state, toggler: action.payload.toggler }
        default:
            return state
    }
}

export default rootReducer

“ Filter.js”组件

import React, { useEffect } from 'react';
import { connect } from 'react-redux'
import { selectCategory, fetchCategories } from '../../../../actions'



const Filter = (props) => {

    // const [minPrice, setMinPrice] = useState(0)
    // const handleMinPrice = event => {
    //     setMinPrice(event.target.value)
    // }

    // const [maxPrice, setMaxPrice] = useState(0)
    // const handleMaxPrice = event => {
    //     setMaxPrice(event.target.value)
    // }

    // const [department, setDepartment] = useState("select")
    // const handleDepartment = event => {
    //     console.log(event.target.value)
    //     setDepartment(event.target.value)
    // }
    // console.log(props);


    const handleChange = event => {
        event.preventDefault()
        props.selectCategory(event.target.value)
    }

    useEffect(() => {
        props.fetchCategories()
    })


    return (
        <div className="filter-form col-12">
            <form id="filter-category">
                <label htmlFor="category">Category</label>
                <select className="col-12" id="category" name="category" size="5" value={props.currentCategory} onChange={(event) => handleChange(event)}>
                    {props.categories.map(category => <option key={category.value} value={category.value}>{category.name}</option>)}
                </select>
            </form>
            {props.currentCategory !== 'any' && <form id="filter-department">
                <label htmlFor="department">Department</label>
                <select className="col-12" id="department" name="department" size="5" value='{department}' onChange='{handleDepartment}'>
                    <option value="select">--- Select ---</option>
                    <option value="desktop PCs">Desktop PCs</option>
                    <option value="laptops">Laptops</option>
                    <option value="gamepads">Gamepads</option>
                    <option value="headphones">Headphones</option>
                    <option value="microphones">Microphones</option>
                    <option value="keyboards">Keyboards</option>
                </select>
            </form>}
            {/* <form id="filter-price">
                <label htmlFor="minimum-price">Min. Price: {minPrice}£</label>
                <input type="range" min="1" max="100" value={minPrice} className="slider col-xs-12" id="minimum-price" onChange={handleMinPrice} />
                <label htmlFor="maximum-price">Max. Price: {maxPrice}£</label>
                <input type="range" min="100" max="1000" value={maxPrice} className="slider col-xs-12" id="maximum-price" onChange={handleMaxPrice} />
            </form> */}
        </div>
    );
}

const mapStateToProps = (state) => {
    return {
        categories: state.categories,
        currentCategory: state.currentCategory
    }
}

const mapDispatchToProps = (dispatch) => {
    return {
        selectCategory: (value) => {
            dispatch(selectCategory(value))
        },
        fetchCategories: () => {
            dispatch(fetchCategories())
        }

    }
}

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

另外,这里是'db.json'

{
  "categories": [
    {
      "id": "1",
      "value": "any",
      "name": "--- Any ---",
      "departments": []
    },
    {
      "id": "2",
      "value": "computers-and-accessories",
      "name": "Computers and Accessories",
      "departments": [
        {
          "id": "1",
          "value": "desktop-pc",
          "name": "Desktop PCs"
        },
        {
          "id": "2",
          "value": "laptops",
          "name": "Laptops"
        },
        {
          "id": "3",
          "value": "keyboards",
          "name": "Keyboards"
        },
        {
          "id": "4",
          "value": "headphones",
          "name": "Headphones"
        },
        {
          "id": "5",
          "value": "mouses",
          "name": "Mouses"
        },
        {
          "id": "6",
          "value": "gamepads",
          "name": "Gamepads"
        }
      ]
    },
    {
      "id": "3",
      "value": "fashion",
      "name": "Fashion",
      "departments": [
        {
          "id": "1",
          "value": "dresses",
          "name": "dresses"
        },
        {
          "id": "2",
          "value": "shoes",
          "name": "Shoes"
        },
        {
          "id": "3",
          "value": "pants",
          "name": "Pants"
        },
        {
          "id": "4",
          "value": "sunglasses",
          "name": "Sunglasses"
        },
        {
          "id": "5",
          "value": "handbags",
          "name": "Handbags"
        },
        {
          "id": "6",
          "value": "hats",
          "name": "Hats"
        }
      ]
    },
    {
      "id": "4",
      "value": "digital-music",
      "name": "Digital Music",
      "departments": [
        {
          "id": "1",
          "value": "rock",
          "name": "Rock"
        },
        {
          "id": "2",
          "value": "pop",
          "name": "Pop"
        },
        {
          "id": "3",
          "value": "house-and-techno",
          "name": "House and Techno"
        },
        {
          "id": "4",
          "value": "trap",
          "name": "Trap"
        },
        {
          "id": "5",
          "value": "indie",
          "name": "Indie"
        },
        {
          "id": "6",
          "value": "hip-hop",
          "name": "Hip-Hop"
        }
      ]
    },
    {
      "id": "5",
      "value": "house",
      "name": "House",
      "departments": [
        {
          "id": "1",
          "value": "kitchen",
          "name": "kitchen"
        },
        {
          "id": "2",
          "value": "garden",
          "name": "Garden"
        },
        {
          "id": "3",
          "value": "bedroom",
          "name": "Bedroom"
        },
        {
          "id": "4",
          "value": "bathroom",
          "name": "Bathroom"
        },
        {
          "id": "5",
          "value": "livingroom",
          "name": "Livingroom"
        },
        {
          "id": "6",
          "value": "cleaning",
          "name": "Cleaning"
        }
      ]
    },
    {
      "id": "6",
      "value": "grocery",
      "name": "Grocery",
      "departments": [
        {
          "id": "1",
          "value": "vegetables",
          "name": "Vegetables"
        },
        {
          "id": "2",
          "value": "pasta and rice",
          "name": "Pasta and Rice"
        },
        {
          "id": "3",
          "value": "snacks",
          "name": "Snacks"
        },
        {
          "id": "4",
          "value": "canned-food",
          "name": "Canned Food"
        },
        {
          "id": "5",
          "value": "frozen",
          "name": "Frozen"
        },
        {
          "id": "6",
          "value": "dairy",
          "name": "Dairy"
        }
      ]
    }
  ]
}

我在这里想念什么?

1 个答案:

答案 0 :(得分:2)

尝试在这样的操作中进行调度,该操作将触发减速器FETCH_CATEGORIES:

export const fetchCategories = () => (dispatch) => {
    fetch("http://localhost:7000/categories")
        .then(response => response.json())
        .then(categories => {
            // **Changes start here
            dispatch ({
                type: FETCH_CATEGORIES,
                payload: categories
            })
            // **Changes end here
        })

}