简体   繁体   English

React 组件道具不会更新

[英]React Component props won't update

this.props.images is not properly updating when I dispatch the array of images.当我发送图像数组时, this.props.images没有正确更新。 The array just displays as empty, though the resulting array is not.该数组仅显示为空,但结果数组不是。

数组截图

I've linked my repo for the project and listed the files that need to be referenced.我已经为该项目链接了我的 repo 并列出了需要引用的文件。

React Web App Repo React Web 应用程序仓库

Furbabies Co Web App Furbabies Co 网络应用程序

The files that you need to look at are as follows:需要查看的文件如下:

  • components/Content/Profile/Images.js组件/内容/配置文件/Images.js
  • components/Content/User.js组件/内容/User.js
  • store/image.js商店/image.js
  • store/images.js商店/images.js

If you want to help with this project by contributing that'd be great!如果你想通过贡献来帮助这个项目,那就太好了! :) :)

maybe you should use the componentWillReceiveProps in the Component life cycle也许你应该在组件生命周期中使用 componentWillReceiveProps

see react docs --> here请参阅反应文档--> 此处

or just use pureComponents (functions nether classes)或者只使用 pureComponents(函数下层类)

pureComponents updates on props by default pureComponents 默认更新 props

I tried running your app, but it didn't work.我试过运行你的应用程序,但没有用。 So the code below is assuming that everything else is set up and working properly in your app.因此,下面的代码假设其他所有内容都已在您的应用程序中设置并正常工作。

Instead of using the class decorator @ , try connecting directly to the class (also, I'd highly recommend cleaning up your code, it's really hard to read).不要使用类装饰器@ ,而是尝试直接连接到类(另外,我强烈建议清理您的代码,它真的很难阅读)。

Several notes:几个注意事项:

  1. Use better declarative names for all of your functions ( this.update() -- update WHAT!?!? While it makes sense to you, to a developer who has never seen your app, they'll ask the same question)为所有函数使用更好的声明性名称( this.update() -- update WHAT!?!? 虽然这对您来说很有意义,但对于从未见过您的应用程序的开发人员来说,他们会问同样的问题)
  2. Follow the recommended way to setup a redux reducer switch/case .按照推荐的方式设置redux reducer switch/case
  3. Combine similar redux state into one reducer.将类似的 redux state 合并为一个 reducer。 For example, you have image and images .例如,您有imageimages What's the difference?有什么不同? If one is a number for indexing and the other is an array for images, that's okay, you can still use a single reducer (as shown below).如果一个是用于索引的数字,另一个是用于图像的数组,那没关系,您仍然可以使用单个reducer(如下所示)。
  4. Create an actions folder to handle Redux actions and a types folder for Redux types创建一个actions文件夹来处理 Redux 动作和一个用于 Redux 类型的types文件夹
  5. Use redux-thunk for async functions (like fetch )redux-thunk用于异步函数(如fetch
  6. Create a separate Upload Images form.创建一个单独的Upload Images表单。 Don't lump it with your Images component.不要将它与您的Images组件混为一谈。
  7. You actually don't need Redux here (unless you're sharing it with other nested components).您实际上并不需要 Redux(除非您与其他嵌套组件共享它)。 You can just use React's local state .你可以只使用 React 的本地state

types/index.js (redux action types) types/index.js (redux 操作类型)

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

reducers/imagesReducer.js (structure your switch/case s like so) 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 creators)动作/图像动作(redux 动作创建者)

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 (displays images -- nothing else; also, allows you to view them one by one via buttons) 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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM