изменить на новое значение состояния с помощью mapDispatchToProps - PullRequest
2 голосов
/ 24 января 2020

Профиль. js

Экран профиля извлекает свои данные из WebApi с использованием приставки и отображает изображение в соответствии с imageUrl. SelectImage () вызывает функцию для пользователей, чтобы открыть галерею и выбрать новое изображение.

После выбора изображения я бы хотел, чтобы изображение отображалось на экране и заменяло текущее значение this.props.items.imageUrl , Я просто запустил Redux и внедрил его в свое приложение. Я хотел бы обновить состояние притока и быть доступным на других экранах, так как изображение будет отображаться и на других экранах. Однако я не могу изменить изображение внутри приложения.

Все данные находятся внутри элементы

          <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 ]

0 голосов
/ 24 января 2020

Вы должны добавить некоторые изменения

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;
  }
}

затем импортируйте updatePicture в ваш файл реакции, соединитесь с вашим классом реакции следующим образом

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.

0 голосов
/ 24 января 2020

Я думаю, что в редукторе есть опечатка:

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

, и, поскольку вы не упомянули, вам потребуется mapStateToProps для сопоставления состояния вашего профиля pi c в редукторе с вашей пропойой.

но здесь возникает другая проблема, ваш реквизит находится в формате объекта (items.imageUrl). но ваше состояние - это просто строка (profilepi c). Если вы не хотите сделать profilepi c объектом, хранящим элементы изображений profilepi c, которые ваш редуктор не делает, вам придется это исправить. Иначе, если вы хотите хранить только один URL-адрес изображения за раз, вам нужно сопоставить состояние редукции с новым реквизитом и установить значение init в качестве значения items.imageUrl.

EDIT: основано на что пояснил OP, вот еще несколько примеров кода, обратите внимание: так как у меня нет целого куска кода, поэтому я не знаю, есть ли какой-нибудь вспомогательный метод для добавления нового редуктора в хранилище и установки значения init. это предпочтительный метод, но только для того, чтобы показать идею 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);

надеюсь, что это поможет. и, пожалуйста, не забудьте починить редуктор

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