Redux - mapStateToProps не работает (React-Native) - PullRequest
0 голосов
/ 15 апреля 2020

Я изучаю Redux и не могу отобразить состояние на моей домашней странице. Я получаю ошибку: «undefined не является объектом, оценивая this.props.titles.allTitles. Ошибка находится в Home, созданном функцией соединения 'Вот код, дайте мне знать, если вам нужны какие-либо другие файлы. Спасибо. Я добавляю больше текста, чтобы соответствовать переполнению стека, спасибо за вашу помощь.

home:


    import React from 'react';
    import { StyleSheet, Text, View, Button } from 'react-native';
    import { connect } from 'react-redux'

    class Home extends React.Component {
        render() {
            return (
                <View>
                    <Text>Redux Test</Text>
                    <Button
                        title='+ new list'
                        onPress={() => 
                            this.props.navigation.navigate('New List')
                        }
                        />

                    <Text>{this.props.titles.allTitles.length}</Text>

                </View>

            )
        }
    }


    const mapStateToProps = (state) => {
        const { titles } = state
        return { titles }
      };

    export default connect(mapStateToProps) (Home);
    ```
    reducer: 
    ```
    import { combineReducers } from 'redux';

    const INITIAL_STATE = {
        allTitles: []
    };

    const tagReducer = (state = INITIAL_STATE, action) => {
        switch (action.type) {
            case 'NEW_LIST':
                return {
                    ...state,
                    allTitles: [...state.allTitles, action.payload.title]
                }


            default: 
                return state;
        }

    };

    const reducers = combineReducers({
        tagReducer
    })

    export default reducers;
    ```
    import React from 'react';
    import { StyleSheet, Text, View, Button, TextInput } from 'react-native';
    import { connect } from 'react-redux';
    import { newList } from '../store/tagActions';


    class List extends React.Component {
        constructor(props){
            super(props);
            this.state = {
                title: ''
            }
        }


        render() {
            return (
                <View style={styles.container}>
                    <TextInput
                        style={styles.title}
                        placeholder='add Title..' 
                        onChangeText={text => this.setState( {title: text} ) }
                    />

                    <Button
                        title='done'
                        onPress={() => {
                            this.props.newList(this.state.title)
                            }
                        }
                    />

                    <Text>{this.state.title}</Text>

                </View>
            )
        }
    }

    const mapStateToProps = (state) => {
        const { allTitles } = state
        return { allTitles }
      };



      export default connect(mapStateToProps, { newList }) (List);

Ответы [ 3 ]

1 голос
/ 15 апреля 2020

На мой взгляд, получить установку Redux довольно сложно. Взглянув на ваш код, я создал небольшой проект React-Native и настроил Redux настолько близко, насколько возможно, к тому, что вы описали в своем вопросе. Надеюсь, мой ответ поможет. Обратите внимание, что все три файла в моем ответе (App. js, Home. js, & titleReducer. js) содержатся в одном каталоге.

Приложение. js

import React from 'react';

import { StyleSheet, Text, View, Button } from 'react-native';

import titleReducer from './titleReducer';

// React-Redux
import { 
  createStore,
  combineReducers,
} from 'redux';
import { 
  connect, 
  Provider 
} from 'react-redux';

// Import Components (Screens)
import Home from './Home';

// Intialize Redux Store
const rootReducer = combineReducers({
  titles: titleReducer
});
const store = createStore(rootReducer);

class App extends React.Component {
  render() {
    return (
      <Provider store={store}>
        <Home/>
      </Provider>
    )
  }
}

export default App;

titleReducer. js

const initialState = {
  allTitles: [],
};

const titleReducer = (state, action) => {

  // check for state undefined to prevent 
  // redux from crashing app on load
  if (typeof state === 'undefined') {
    return {...initialState};
  }

  switch (action.type) {
    case 'ADD_TITLE':
      const newState = {...state};
      const newTitle = action.payload;
      newState.allTitles.push(newTitle);
      return newState;
    default:
      return {...state};
  }

  // If none of the conditions above are true,
  // simply return a copy of the current state
  return {...state};
};

export default titleReducer;

Home. js

import React from 'react';

import { StyleSheet, Text, View, Button } from 'react-native';

import { 
  connect, 
  Provider 
} from 'react-redux';

function randomTitle() {
  return Math.random().toString();
}

class Home extends React.Component {
  render() {
    return (
      <View>
        <Text>Redux Test</Text>
        <Button 
          title="Add Title"
          onPress={ () => this.props.addTitle(randomTitle()) }/>
        <Text>{this.props.titles.allTitles.length}</Text> 
      </View>
    )
  }
}

const mapDispatchToProps = dispatch => {
  return {
    addTitle: (payload) => dispatch({type: 'ADD_TITLE', payload: payload}),
  };
};
const mapStateToProps = (state) => {
  return { 
    titles: state.titles,
  };
};
export default connect(mapStateToProps, mapDispatchToProps)(Home);
1 голос
/ 15 апреля 2020

Я думаю, что вы забыли определить магазин для вашего приложения. Go в свой root класс (приложение. js или что-то) и определите ваши редукторы для своего магазина:

const store = createStore(tagReducer)

или, если у вас есть несколько редукторов, вы можете объединить их в одну строку:

const store = createStore(combineReducers({
   tag: tagReducer,
   someOther: otherReducer
}));

Надеюсь, что это решит вашу проблему.

1 голос
/ 15 апреля 2020

В вашем редукторе у вас есть следующее -

allTitles: [...state.allTitles, action.payload.title]

Когда вы это сделаете, я не вижу title в состоянии избыточности.

const mapStateToProps = (state) => {
    const { titles } = state
    return { titles }
  };

Вам нужно сделать

const mapStateToProps = (state) => {
    const { allTitles } = state
    return { allTitles }
  };

Затем сделать {this.props.allTitles.length} внутри оператора рендеринга

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