javascript - React Component Prop 不会更新

标签 javascript reactjs redux react-redux react-props

当我分派(dispatch)图像数组时,

this.props.images 没有正确更新。该数组只是显示为空,但生成的数组不是。

screenshot of arrays

我已经为项目链接了我的 repo,并列出了需要引用的文件。

React Web App Repo

Furbabies Co Web App

需要查看的文件如下:

  • 组件/Content/Profile/Images.js
  • 组件/Content/User.js
  • store/image.js
  • store/images.js

如果您想通过贡献来帮助这个项目,那就太好了! :)

最佳答案

我尝试运行您的应用程序,但没有成功。所以下面的代码假设其他一切都已设置并在您的应用程序中正常工作。

不要使用类装饰器 @,而是尝试直接连接到类(另外,我强烈建议清理您的代码,它真的很难阅读)。

几点说明:

  1. 为您的所有函数使用更好的声明性名称(this.update() -- 更新什么!?!?虽然这对您来说很有意义,但对于从未见过您的应用程序的开发人员来说,他们会问同样的问题)
  2. 按照推荐的方式设置 redux reducer switch/case .
  3. 将类似的 redux 状态合并到一个 reducer 中。例如,您有 imageimages。有什么不同?如果一个是用于索引的数字,另一个是用于图像的数组,那没关系,您仍然可以使用单个 reducer(如下所示)。
  4. 创建一个 actions 文件夹来处理 Redux 操作,并创建一个 types 文件夹来处理 Redux 类型
  5. 使用redux-thunk对于异步函数(如 fetch)
  6. 创建一个单独的上传图片 表单。不要将它与您的 Images 组件混为一谈。
  7. 实际上您在这里不需要 Redux(除非您与其他嵌套组件共享它)。您可以只使用 React 的本地 state

types/index.js(redux Action 类型)

export const UPDATE_IMAGE_INDEX = "UPDATE_IMAGE_INDEX";
export const UPDATE_IMAGES = "UPDATE_IMAGES";

reducers/imagesReducer.js(像这样构造您的switch/case)

const initialState = {
   index: 0,
   data: []
}

const imagesReducer = (state=initialState, { type, payload }) => { //es6 destructing -- type=action.type, payload=action.payload
  switch (type) {
    case 'UPDATE_IMAGE_INDEX':
      return { ...state, index: payload } // accessible via state.images.index
    case 'UDPATE_IMAGES':
      return {...state, data: payload } // accessible via state.images.data
    default:
      return state
  }
};

export default imagesReducer;

actions/imageActions(redux Action 创建者)

import * as types from '../types';

// the following is a Redux thunk action (thunk handles returned async functions -- you have to install it and add it as middleware)
export const fetchImages = (id, type) => dispatch => (
  fetch(`/images/${type}/${id}`) // fetch images
    .then(res => res.json()) // turn result into JSON
    .then(({ result }) => dispatch({ type: types.UPDATE_IMAGES, payload: result })) // send result to `imagesReducer`
    .catch(() => console.log('Network error...'));
)

// this updates the image index
export const updateImageIndex = payload => dispatch => (
  dispatch({ type: types.UPDATE_IMAGE_INDEX, payload })
)

// this should upload an image, save it, then return all current images
export const uploadImage = (type, id, data) => dispatch => (
   fetch(`/images/${type}/${id}`, {
      method: 'POST',
      body: data
     }
   )
   .then(res => res.json())
   .then(({ result }) => dispatch({ type: types.UPDATE_IMAGES, payload: result }))
   .catch(() => dispatch({ type: 'UPDATE_ERROR', payload: { message: 'Network error...try again later!'} }));
)

components/Content/Profile/ShowImages.js(显示图像——仅此而已;还允许您通过按钮一张一张地查看它们)

import React, { PureComponent } from 'react'
import { connect } from 'react-redux'
import { fetchImages, updateImageIndex } from '../../../actions/imageActions';

class ShowImages extends PureComponent {   
  componentDidMount = () => {
    inputs.lazyload(`/css/images.min.css`).catch(() => console.log('Network error...'));
    this.props.fetchImages(this.props.type, this.props.id); // fetches images via redux action creator shown above
  }

  handlePrevClick = e => {
    const { index, images } = this.props;
    if (index-1 <== images.length) {
       this.props.updateImageIndex(index-1); // reduces redux image index by 1 via redux action creator shown above
    }
  }

  handleNextClick = () => {
    const { index, images } = this.props;   
    if (index+1 <== images.length) {
       this.props.updateImageIndex(index+1); // increases redux image index by 1 via redux action creator shown above
    }
  }

  // ideally this should be done BEFORE being sent to the front-end, as is, every time this.props.index is updated, this has resort them -- ruins client-side performance and wastes resources.
  sortImages = () => {
   return this.props.images.sort((a, b) => {
      if (a.isDefault && b.isDefault) return a.src.localeCompare(b.src);
      return a.isDefault || b.isDefault;
    });
  }


  render = () => {
    const { index, images } = this.props;
    const sortedImages = this.sortImages();
    const prev = images.length && index > 0 ? '<' : '+';
    const next = images.length && index < images.length ? '>' : '+';

    return (
      <div className='images'>
        <button className='prev' onClick={this.handlePrevClick}>
          {prev}
        </button>
        <img src={sortedImages[index]} />
        <button className='next' onClick={this.handleNextClick}>
          {next}
        </button>
      </div>
    );
  }
}

const mapStateToProps = state => ({
   images: state.images.data,
   index: state.images.index,
   user: state.user,
   type: store.current.type
})

const mapDispatchToProps = dispatch => ({ fetchImages, updateImageIndex }); 


export default connect(mapStateToProps, mapDispatchToProps)(ShowImages)

关于javascript - React Component Prop 不会更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52788453/

相关文章:

javascript - 一键执行双重操作 jquery

javascript - 为什么我的 Polymer iron 图标出现在我的导航纸输入下方?

javascript 对象原型(prototype) this 引用

reactjs - 更新嵌套对象时 Redux 不重新渲染

javascript - 通过单击按钮打开抽屉时禁用文本框

javascript - 蜗牛矩阵数组javascript

javascript - lodash 中的值方法未按预期工作

javascript - 如果在React中的onClick中放置两个函数,则只有其中一个可以工作

javascript - react悬念如何保持在同一页面-LazyLoading

javascript - Store 没有带有 mergeReducer 的有效 reducer