Я использую React, Redux и Firebase для создания веб-сайта. Пользователи могут редактировать свои профили на странице «настроек». Моя цель дизайна и подходы следующие:
Цель дизайна: Существующая информация профиля пользователя (изображение профиля, имя и т. Д. c.) Отображается после загрузки страницы.
Подход: Я устанавливаю для всех полей данных пользователей пустые строки / массив в состоянии компонента «настройки» и использую mapStateToProps, чтобы передать в компонент существующий профиль пользователя и установить состояние используя componentDidMount. Каждое поле данных имеет свой собственный handleXXXChange, поэтому, если пользователи не изменяют поле данных, его существующее значение будет передано в качестве существующего значения объекту действия Redux с именем editProfile, который обновляет документ пользователя в Firebase.
Проблемы, с которыми я столкнулся: 1. componentDidMount вызывается только один раз в течение жизненного цикла компонента, поэтому, если пользователь обновляет страницу, для всех полей в состоянии будет установлено значение «undefined». 2. Странно, что когда я нажал кнопку «Загрузить изображение профиля», страница «перезагрузилась» и в конце URL-адреса появился вопросительный знак. Действительно, появилось окно, в котором пользователи могли выбрать файл изображения, но выбранное изображение не удалось загрузить в хранилище firebase. Это очень странно, потому что те же самые методы uploadImage и openFiles работали до того, как я добавил componentDidMount для достижения упомянутой выше цели.
Большое спасибо за ваше терпение и помощь!
" Компонент настроек "
class Settings extends Component {
state = {
firstname: "",
lastname: "",
gender: "",
institution: "",
role: "",
selfdescription: "",
areasofinterest: "",
email: "",
profileimage: ""
};
componentDidMount() {
const { profile, auth } = this.props;
const id = auth.uid;
const image = firebase.storage().ref(`images/`+id);
image.getDownloadURL().then((url) => this.setState({ profileimage: url }));
this.setState({
firstname: profile.first_name,
lastname: profile.last_name,
gender: profile.gender,
institution: profile.institution,
role: profile.role,
selfdescription: profile.self_description,
areasofinterest: profile.areas_of_interest,
email: profile.email
}
)
}
handleSubmit = (e) => {
e.preventDefault();
const { auth } = this.props;
this.props.editProfile(this.state, auth.uid, this.props.history);
}
uploadImage = (e) => {
e.preventDefault();
const image = e.target.files[0];
const { auth } = this.props;
firebase.storage().ref('images/'+auth.uid).put(image);
}
openFiles = (e) => {
const input = document.getElementById("imageinput");
input.click();
}
handleFirstNameChange = (e) => {
e.preventDefault();
this.setState({ firstname: document.getElementById("fn").value });
}
handleLastNameChange = (e) => {
e.preventDefault();
this.setState({ lastname : document.getElementById("ln").value });
}
......
render(){
const { auth, profile } = this.props;
return(
<form>
<img src={firebase.storage().ref(`images/`+auth.uid).getDownloadURL()}></img>
<input type="file" id="imageinput" hidden="hidden" onChange={this.uploadImage}></input>
<button onClick={this.openFiles}>Upload Profile Image</button>
<span>First Name</span>
<input id="fn" type="text" placeholder={profile.first_name} onChange={this.handleFirstNameChange}></input>
<span><br/>Last Name</span>
<input id="ln" placeholder={profile.last_name} onChange={this.handleLastNameChange}></input>
......
<button onClick={this.handleSubmit}>Save</button>
</form>
)
}
}
const mapStateToProps = (state) => {
return {
profile: state.firebase.profile,
auth: state.firebase.auth
}
}
export default connect(mapStateToProps, {editProfile} )(withRouter(Settings));
" editProfile "Объект действия Redux (я почти уверен, что с этой частью все в порядке, но просто поместите ее, чтобы мой код был более понятным):
export const editProfile = (credentials, userid, history) => (dispatch, getState) => {
const profile = getState().firebase.profile;
firebase.firestore().collection("users").doc(userid).update({
first_name: credentials.firstname,
last_name: credentials.lastname,
gender: credentials.gender,
institution: credentials.institution,
role: credentials.role,
self_description: credentials.selfdescription,
areas_of_interest: credentials.areasofinterest,
email: credentials.email
})
.then(() => {
dispatch({ type: EDIT_SUCCESS });
history.push(profile.profile_url);
})
}