使用 mapDispatchToProps 更改状态的新值

IT技术 javascript reactjs react-native redux react-redux
2021-05-05 04:20:55

配置文件.js

Profile 屏幕使用 redux 从 WebApi 获取其数据,并根据 imageUrl 显示图像。SelectImage() 调用函数让用户打开图库并选择新图像。

选择图像后,我希望图像显示在屏幕上并替换this.props.items.imageUrl. 我刚刚启动了 redux 并将其实现到我的应用程序中。我想更新 redux 的状态并在其他屏幕上访问,因为图片也会显示在其他屏幕上。但是,我无法更改应用程序内的图像。

所有数据都在items里面

          <TouchableOpacity
            onPress={() => this.selectImage()}>
            <View style={styles.piccontainer}>
              <Image
                source={{ uri: this.props.items.imageUrl }}
                style={styles.photo} />
            </View>
          </TouchableOpacity>
          <TouchableOpacity style={styles.button}
              onPress={() => {
                this.uploadImage();
                this.goBack()
              }}>
              <View>
                <Text style={styles.text}>Save</Text>
              </View>
          </TouchableOpacity>

这是我的 selectImage() 函数

  selectImage = async () => {
    let result = await ImagePicker.launchImageLibraryAsync({
      mediaTypes: ImagePicker.MediaTypeOptions.All,
      allowsEditing: true,
      aspect: [4, 3],
      quality: 1
    });
    let file = result.uri
    if (!result.cancelled) {
      this.updatePicture(file)
    }
  }

我相信我必须mapDispatchToProps采取行动。

function mapDispatchToProps(dispatch) {
  return {
    updatePicture: file => {dispatch(updatePicture(file))}
  }
}

调用该函数后我迷路了,我是否将减速器和动作放在与获取配置文件数据的函数相同的位置?我是否创建了一个新文件,但如果我这样做了,我将初始状态设置为什么?感谢您的帮助。我很感激。

profileReducer.js

const initialState = {
  profilepic: '',
};

export default function updateprofileReducer(state = initialState, action) {
  switch (action.type) {
    case UPDATE_PICTURE:
      return {
        ...state,
        profilepic: action.payload.file
      }
    default:
      return state;
  }
}

profileAction.js

export const updatePicture = file => ({
    type: UPDATE_PICTURE,
    payload: file
})
2个回答

我认为减速器中有一个错字:

    case UPDATE_PICTURE:
      return {
        ...state,
        profilepic: action.payload, // <--- this instead of action.payload.file 
      }

并且由于您没有提到,您将需要 mapStateToProps 将您在 redux 中的 profilepic 状态映射到您的props。

但这里带来了另一个问题,你的props是对象的格式(items.imageUrl)。但你的状态只是一个字符串(profilepic)。除非您打算使 profilepic 成为存储您的减速器没有这样做的 profilepic 图像项目的对象,否则您将需要修复它。否则,如果您打算一次只存储一个图像 url,则需要将 redux 状态映射到一个新的 prop,并将 init 值设置为您的 items.imageUrl 值。

编辑:基于 OP 澄清的内容,这里有更多示例代码,请注意:由于我没有完整的代码,所以我不知道是否有任何帮助方法可以将新的减速器注入商店并设置初始值。这是更喜欢的方法,但只是为了展示 mapStateToProps 的想法:

<TouchableOpacity onPress={() => this.selectImage()}>
  <View style={styles.piccontainer}>
    <Image
      source={{ uri: this.props.imageUrlFromRedux || this.props.items.imageUrl }}
      style={styles.photo}
    />
  </View>
</TouchableOpacity>

然后你定义了 mapStateToProps

const mapStateToProps = state => ({
  imageUrlFromRedux: state.profilepic,
});

export default connect(mapStateToProps, mapDispatchToProps)(YourComponent);

希望这有帮助。请记住修理你的减速机

您应该添加一些更改

profileAction.js

export const profileAction = file => ({
    type: UPDATE_PICTURE,
    payload: file
})

profileReducer.js

import {profileAction} from 'profileAction.js';

export function updatePicture (file) {
    return (dispatch)=> {
        //some action with file
        dispatch(profileAction(file)); 
    };
}

export default function updateprofileReducer(state = initialState, action) {
  switch (action.type) {
    case UPDATE_PICTURE:
      return {
        ...state,
        profilepic: action.payload.file
      }
    default:
      return state;
  }
}

然后在你的react文件中导入 updatePicture,像这样连接你的react类

export default connect(mapStateToProps, mapDispatchToProps)(YourComponent);

像这样替换 mapDispatchToprops

function mapDispatchToProps(dispatch) {
  return {
    updatePicture: file => dispatch(updatePicture(file))
  }
}

您的selectImage函数有误你应该像这样替换这个代码片段

 if(!result.cancelled) {
      this.props.updatePicture(file);
  }

你的 updatePicture 函数只能从 props 获得。