将redux操作映射/传递给无状态组件

时间:2018-03-26 14:34:48

标签: reactjs react-redux

将我的一个组件(Profile.js)从类更改为函数以简化并具有更清晰的代码后,onClick触发redux操作(如)不再执行任何操作。

有些人指出行动需要采用不同的地图,但我不确定为什么因为我还是还不熟悉还原因为它为什么它作为一个班级工作正常而感到困惑但不是一种功能。

令人困惑的是,我还使用反应thunk来使事情变得异步。

user.js的

import { fetchUser, like } from '../../actions/userActions';

class User extends React.Component {
    componentDidMount() {
        const { username } = this.props.match.params;
        this.props.fetchUser(username);
    }

    render() {
        const { like, user } = this.props;

        return (
            <Profile user={user} like={like} />
        )
    }
}

const mapStateToProps = state => ({
    user: state.store.user
});


export default connect(mapStateToProps, {fetchUser, like})(User);

Profile.js之前

import { like, user } from '../../actions/userActions';

class Profile extends React.Component {
    const { like, user } = this.props

    return (
        <a onClick={() => like(user.username)}>Like</a>
    )
}

export default connect (mapStateToProps, {like}){Profile)

Profile.js

之后
const Profile = (props) => {
    const { like, user } = props

    return (
        <a onClick={() => like(user.username)}>Like</a>
    )
}

actions.js

const url = 'http://localhost:3001'

function handleErrors(response) {
    if (!response.ok) {
        throw Error(response.statusText);
    }
    return response;
}

export const like = (username) => dispatch => {
    fetch(`${url}/like/${username}`, {credentials: 'include', method: 'post'})
    .then(handleErrors)
    .then(res => res.json())
    .then(res =>
        dispatch({
            type: LIKE,
            payload: res
    })
  )
  .catch(error => console.error('Error:', error))
}


export const fetchUser = (username) => dispatch => {
    fetch(`${url}/${username}`, {credentials: 'include'})
    .then(handleErrors)
    .then(res => res.json())
    .then(res =>
    dispatch({
        type: FETCH_USER,
        payload: res
    })
  ) 
  .catch(error => console.error('Error:', error)) 
}

reducers.js

export default function(state = initialState, action) {
    switch (action.type) {

    case FETCH_USER:
        return {
        ...state,
        user: action.payload.user
    };    

    case LIKE:
        return {
        ...state,
            user: {
                ...state.user,
                meta: {
                    ...state.user.meta,
                    like: action.payload.like
                }
            }
        };

store.js

const initialState = {};
const middleware = [thunk];

const store = createStore(
    rootReducer,
    initialState,
    compose(
        applyMiddleware(...middleware),
        window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
  )
);

export default store;

在Profile.js中的console.log

const Profile = (props) => {
    const { user, like } = props
    console.log(like)

ƒ like(username) {
  return function (dispatch) {
    fetch(url + '/like/' + username, { credentials: 'include', method: 'post' }).then(handleErrors).then(function (res) {
      return res.json();
    …

如果我要创建一个正常的功能,如

const test = () => { console.log('test') }

并更改 Profile.js 中的onClick={}以使用它,它可以正常工作。

1 个答案:

答案 0 :(得分:1)

您应该在User组件中创建处理程序,在那里调用您的操作创建者并将其作为回调传递给子Profile组件。

因此,您的代码将如下所示:

import { like } from '../../actions/userActions';

class User extends React.Component {
    ...

    onClickHandler = username => {
        return () => {
            this.props.like(username);
        }
    }

    render() {
       const { user } = this.props;
       return <Profile user={user} onClickHandler={this.onClickHandler} />   
    }
}

const mapStateToProps = state => ({
    user: state.store.user
});

export default connect(mapStateToProps, {fetchUser, like})(User);

然后,在onClickHandler组件中调用Profile

const Profile = props => {
    const { onClickHandler, user } = props;

    return (
        <button onClick={onClickHandler(user.username)}>Like</button>
    )
}

希望它会有所帮助。