Рендеринг массива объектов из магазина Redux в качестве компонентов React - PullRequest
1 голос
/ 10 января 2020

Я пытаюсь показать свое начальное состояние из моего магазина. Я знаю, что мой код неверен, но я надеюсь изучить самый простой метод для этого. Могу ли я просто получать данные из магазина с реквизитом? или мне нужно какое-то событие жизненного цикла для нацеливания данных в хранилище?

Вот моя текущая попытка: я отредактировал это, чтобы включить мой редуктор, и я обновил свой компонент согласно комментариям ниже.


//store .js

import { createStore, applyMiddleware,compose } from 'redux';
import thunk from 'redux-thunk';
import rootReducer from './reducers'; //the index.js file

const initialState = {

}

const middleware = [thunk]

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

export default store;

Теперь, когда я пытаюсь отобразить мои реквизиты в следующем компоненте, я получаю ошибку:

this.props.properties.map is not a function

//Properties component that renders a map of my props

import React, { Component } from 'react'
import PropTypes from 'prop-types';
import {connect} from 'react-redux';
import {getListings} from '../actions/postActions';

 class Properties extends Component {

    componentDidMount(){
        getListings()
    }

    render() {
        const properties = this.props.properties.map(property => (
            <div key = {property.id}>
                <h3>{property.propertyName}</h3>
                <div style={{width: '4em', height:'4em', backgroundColor: 'blue'}}>image</div>
                <p>{property.footage}</p>
                <p>{property.address}</p>
                <p>{property.price}</p>
            </div>
        ))
        return (
            <div>
                <h1>Current Listings</h1>
                    {properties}
            </div> 
        )
    }
}
Properties.propTypes = {
    properties: PropTypes.array.isRequired,
    newListing: PropTypes.object
}

const mapStateToProps = state =>({
    properties: state.properties.properties,
    newListing: state.properties.newListing
});
export default connect(mapStateToProps)(Properties)

//my actionsHandler.js

import {GET_LISTINGS, NEW_LISTING} from './types';


export function newProperty(formdata){
    return function(dispatch){
        dispatch({
            type: NEW_LISTING,
            payload: formdata
        })
    }
}

export function getListings(form){
    return function(dispatch){
        dispatch({
            type: GET_LISTINGS,
        })
    }
}
//my reducer
import {NEW_LISTING, GET_LISTINGS} from '../actions/types';

const initialState={
    properties: [
        {
            id: 1,
            propertyName: 'The boogaloo',
            footage: '3500 sqft',
            address: '123 hill bounty rd',
            price:'$ 350,000.00'
        }
    ],
    newListing: {}
}

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

        case NEW_LISTING:
            return{
                ...state,
                properties:state.properties.push(action.payload)
            }
        case GET_LISTINGS:
            return{
                state
            }

        default:
            return state
    }
}

Ответы [ 3 ]

3 голосов
/ 10 января 2020

используйте метод жизненного цикла для обновления компонента

, как метод shouldComponentUpdate,

изменение реквизитов Не вызывает перерисовку, только изменение состояния вызывает перерисовку, в этом случае сохраняются реквизиты как состояние также решение (неуместно)

1 голос
/ 10 января 2020

Ваш общий подход в целом жизнеспособен, хотя необходимо внести определенные исправления:

  • ожидается, что ваше состояние будет объектом (а не массивом, каким он является в настоящее время)
  • in Чтобы весь массив объектов отображался в виде набора элементов React, вы можете захотеть обернуть их в некоторый родительский компонент и map() свои отдельные сообщения в виде небольших компонентов, которые получают соответствующий объект в качестве реквизита от родительского компонента

Вы можете запросить следующую live-демонстрацию в качестве ссылки:

//dependencies
const { render } = ReactDOM,
      { createStore } = Redux,
      { connect, Provider } = ReactRedux
      
//initial state, doomy reducer and basic store (no middleware)
const initialState = {posts:[{id:'0',propertyName:'house',footage:'1800 sqft',address:'108 boogaloo dr. thisplace, CA',price:'$145,300.00'},{id:'1',propertyName:'closet',footage:'110 sqft',address:'23 dirt dr. badplace, NC',price:'$3'},{id:'2',propertyName:'garage',footage:'1000 sqft',address:'10 meadow st. decent, NY',price:'$100,000.00'},{id:'3',propertyName:'fishing shack',footage:'500 sqft',address:'108 fishy dr. forestgrove, NJ',price:'$200,300.00'},{id:'4',propertyName:'huge mansion',footage:'8000 sqft',address:'32 T-Pain st. onlytwentythree, WI',price:'$100.00'},{id:'5',propertyName:'dog house',footage:'200 sqft',address:'2367 goodboy dr. borks, KA',price:'$1000.00'},{id:'6',propertyName:'beehive',footage:'too big to measure',address:'108 stingya dr. Bidibi, NJ',price:'$300.00'},{id:'7',propertyName:'my house',footage:'4000 sqft',address:'42 treeface dr. bigwoods, FL',price:'$190,300.00'},]},
      appReducer = (state=initialState, action) => state,
      store = createStore(appReducer)
//post ui component
const Post = ({propertyName, footage, address, price}) => (
  <div>
    <h3>{propertyName}</h3>
    <p>footage: {footage}</p>
    <p>address: {address}</p>
    <p>price: {price}</p>
  </div>
)
//wrapper ui component relying on storedPosts property
//that will get connected to global state posts later on
const PostBoard = ({storedPosts}) => (
  <div>
    {storedPosts.map((post, key) => <Post key={key} {...post} />)}
  </div>
)
//connect storedPosts to global state posts
const mapStateToProps = ({posts}) => ({storedPosts: posts}),
      PostBoardComponent = connect(mapStateToProps)(PostBoard)
//render Redux Provider
render (
  <Provider store={store}>
    <PostBoardComponent />
  </Provider>,
  document.getElementById('root')
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.12.0/umd/react.production.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.11.0/umd/react-dom.production.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/redux/4.0.5/redux.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/react-redux/7.1.3/react-redux.min.js"></script><div id="root"></div>
1 голос
/ 10 января 2020

В редуксе вы будете определять начальное состояние в редукторе и будете выполнять некоторое обновление или удаление данных из состояния с помощью действий и сохраните, т.е. вы обновляете объект, объект начального состояния будет обновлен. случаях вам нужно исходное состояние напрямую. Итак, вам нужно сделать копию исходного состояния объекта и выполнить на нем задачи. При обновлении нового объекта начальное состояние не будет иметь никакого эффекта.

Обновление с помощью компонентов можно выполнить путем прямой отправки действия от компонента, например mapdispatchtoProps.

Вы можете получить доступ ко всем данным хранилища в компоненте, подключив его, например, connect (mapStatetoProps, mapDispacthtoProps).

mapSatettoProps предоставит вам данные о состоянии хранилища. Вы можете изменить его или сделать все, что захотите. Доступ к состоянию можно сделать и в компоненте, но вы получите обновленный.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...