如何将更改的状态发送到 react-native 中的组件?

Posted

技术标签:

【中文标题】如何将更改的状态发送到 react-native 中的组件?【英文标题】:How to send changed state to component in react-native? 【发布时间】:2018-11-12 20:28:46 【问题描述】:

我是 react 和 react-native 的初学者。 我正在使用 react 16、react-thunk、react-redux。

我正在尝试获取我已经从 firestore 创建的类别。 起初,我使用connect() 调用action,然后,我使用thunk 键入action,也从firestore 获取数据。 最后,我在 reducer 中返回了新的状态。 当然,我不知道redux过程,所以请给一些提示。

这是我的代码。谢谢。

CategoryImageList.js(组件)

...

class CategoryImageList extends Component 
  componentWillMount() 
    this.props.getCategory();
  

  renderImages() 
      return this.state.categories.map(category =>
          <CategoryImageCard key=category.imgName category=category/>
      );
  

  render() 
    return (
        <ScrollView>
            /*this.renderImages()*/
        </ScrollView>
    );
  


export default connect(null, getCategory)(CategoryImageList);

category.js(动作)

...
export const getCategory = () => 
  return (dispatch) =>  //using redux-thunk here... do check it out
    getCategories()
        .then(querySnapshot => 
            const test = [];
            querySnapshot.forEach((doc) => 
                test.push(
                
                    imgName : doc.data()['imgName'],
                    name : doc.data()['name']
                );
            );

            dispatch( type: GET_CATEGORY, payload: test );
        );
  ;
;

CategoryReducers.js(减速器)

...

const categoryInitialState = 
  name: [],
  imgName: []


export const CategoryReducer = (state = categoryInitialState, action) => 
  switch (action.type) 
    case GET_CATEGORY:
        console.log(action);
        return  ...state, categoryImg: 
            name: action.payload.name,
            imgName: action.payload.imgName
        ;

    default:
        return state;
    

App.js

...
type Props = ;
export default class App extends Component<Props> 
    render() 
        const store = createStore(reducers, , applyMiddleware(ReduxThunk));
        return (
        <Provider store=store>
            <View style=flex:1>
                <Header headerText='FoodUp'/>
                <CategoryImageList />
            </View>
        </Provider>
    );
  

reducers/index.js

import  combineReducers  from 'redux';
import  CategoryReducer  from './CategoryReducer';

export default combineReducers(
    categories: CategoryReducer
);

更新 Firebase.js

const config = 
  ...
;

firebase.initializeApp(config);
const db = firebase.firestore();
const storage = firebase.storage();
const settings = timestampsInSnapshots: true;
db.settings(settings);

export const getCategories = () => 
  return db.collection('categories').get();


export const getCategoryImg = (categoryName, imgName) => 
  const ref = storage.ref(`category/$categoryName/$imgName`);
  return ref.getDownloadURL();

【问题讨论】:

几件事,您需要将您的商店映射到您的组件,以便它可以访问商店数据。然后你可以在你的组件中使用 this.props.data 来访问 store。 redux.js.org/basics/usage-with-react 【参考方案1】:

mapStateToProps 将 Store 状态作为参数/参数(由 react-redux::connect 提供),用于将组件与 store 状态的特定部分链接。在您的情况下,您可以像这样使用。您可以在组件中使用 name、imgName 作为 props

const mapStateToProps = (categories) => 
    const  name, imgName  = categories;
    return name, imgName;
;
export default connect(mapStateToProps, getCategory)(CategoryImageList);

【讨论】:

感谢您的回复!我更新了我的帖子。 MY_STORE_NAME 是什么?我是这样写的,createStore(reducers, , applyMiddleware(ReduxThunk) @MingyuJeon createStore(reducers, , applyMiddleware(ReduxThunk) 中的 reducers 是什么?在那个reducers 文件中,你可以看到你所有的reducer 名称。如果您的商店是这样的,则没有 STORE_NAME。你只有 REDUCER_NAME。你也可以发布reducers 文件吗? 我更新了我的帖子。我不知道如何调用行动。可以使用connect(mapStateToProps, getCategory)(CategoryImage); getCategory 调用action,这是reducer 中的一个函数。 @MingyuJeon 我已经更新了我的答案。减速器名称为 categories 我收到了这个错误。 Invariant Violation: CategoryImageList(...): Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null. 这是因为我在 render() 中没有返回任何内容吗?那我应该返回什么?【参考方案2】:

您必须将 mapstateToProps 添加到您的连接中,例如,

const mapStateToProps = (state: any) => 
  return 
    name: state.categories.name,
    imageName:state.categories.imageName
  ;


export default connect(mapStateToProps)(CategoryImageList)

然后,您将能够访问名称和图像名称,例如, this.props.namethis.props.imageName

编辑:要分派GET_CATEGORY,您可以使用 mapDispatchToProps 或执行 getCategory 并从您的组件中分派,例如,

import getCategory from './category'

 componentWillMount() 
    this.props.getCategory(this.props.dispatch);
  

并将 getCategory 函数更改为,

export const getCategory = (dispatch) => 
...
dispatch( type: GET_CATEGORY, payload: test );
...

【讨论】:

您好,感谢您的回复。我想我的动作文件(category.js)永远不会被调用。因此,由于 reducer 的初始化,状态为 imgName:[], name:[]。我不知道如何在CategoryImageList.js 组件中调用操作。 我已经编辑了答案以包括对您的评论的回答 CategoryImageList.js组件状态的每个属性都是undefined。我认为这是因为action.payloadarray。在这种情况下,我该如何返回状态? 请贴出getCategories()的代码,因为我猜这是一个永远不会被调用的承诺调用。 那是在category.js。我认为它返回 undefined 的原因是 action.payloadarray 的类型。

以上是关于如何将更改的状态发送到 react-native 中的组件?的主要内容,如果未能解决你的问题,请参考以下文章

如何将参数从 React-Native 发送到 Native

如何更改按钮状态并将操作发送到 redux?

React-Native iOS 状态栏

为啥组件在状态更改后不重新渲染。在 react-native 函数组件中

在 react-native 中显示/隐藏状态更改的组件时出错

使用 Ionic 2,您如何通过登录后将您发送到另一个页面的模式来更改基于登录状态的按钮?