#javascript #reactjs
#javascript #reactjs
Вопрос:
Я новичок в React и пытаюсь выполнить простой вход в систему с помощью одного API. Соединение работает нормально, поэтому я хочу создать div при сбое входа в систему.
Например, один div «Неверный пользователь или пароль» после предупреждения («НЕ ВОЙТИ»)
Я читал документацию stackoverflow и react, но у меня есть сомнения, потому что я хочу манипулировать DOM вне рендеринга.
Например, этот код:
render() {
var renderedOutput = arr.map(item => <div> {item} </div>)
return (
<div>
{renderedOutput}
</div>
);
}
что-то вроде этого var. Возможно, это ошибка очень новичка, но я застрял. Благодарим за помощь и сожалеем о проблемах.
import *;
class App extends Component {
handleSubmit = e => {
e.preventDefault();
const user = {
usuario: this.usuario.value,
contraseña: this.password.value
};
axios.post(`http://api`, user).then(res => {
this.setState({
data: res.data,
loading: true
});
if (Object.keys(res.data).length > 0) {
alert("LOGIN");
} else {
alert("NOT LOGIN");
}
console.log(res.data);
});
}
render() {
return (
<Container>
<Form onSubmit={this.handleSubmit}>
<Row>
<Col md="4"> </Col>{" "}
<Col md="4">
<Card>
<CardBody>
<FormGroup>
<InputGroup>
<InputGroupAddon addonType="append">
<InputGroupText>
<FontAwesomeIcon icon={faUser} />{" "}
</InputGroupText>{" "}
</InputGroupAddon>{" "}
<Input
placeholder="Usuario"
type="text"
innerRef={element => {
this.usuario = element;
}}
/>{" "}
</InputGroup>{" "}
</FormGroup>
<FormGroup>
<InputGroup>
<InputGroupAddon addonType="append">
<InputGroupText>
<FontAwesomeIcon icon={faKey} />{" "}
</InputGroupText>{" "}
</InputGroupAddon>{" "}
<Input
placeholder="Password"
type="password"
innerRef={element => {
this.password = element;
}}
/>{" "}
</InputGroup>{" "}
</FormGroup>
<Row>
<Col md="8"> </Col>{" "}
<Col md="4">
<Button color="success"> Login </Button>{" "}
</Col>{" "}
</Row>{" "}
</CardBody>{" "}
</Card>{" "}
</Col>{" "}
<Col md="4"> </Col>{" "}
</Row>{" "}
</Form>
</Container>
);
}
}
export default App;
Комментарии:
1. Старайтесь избегать прямых манипуляций с DOM в React, если можете. Вы могли бы добавить фрагмент состояния, называемый, например
error
, который вы обновляете при получении ошибки, и использовать его для отображения ошибки в методе рендеринга.
Ответ №1:
Вам не нужно выполнять какие-либо ручные манипуляции с DOM для решения проблем такого типа. «Правильным» способом сделать это было бы обновление state ( setState
) после завершения вашего асинхронного запроса, что приведет к повторному рендерингу. Вы можете сохранять ошибки, если запрос завершается неудачно, и очищать их, если запрос выполнен успешно (вы также, вероятно, уйдете с этой страницы при успешном входе в систему, но это выходит за рамки).
Вот тривиальный рабочий пример, который должен продемонстрировать, как вы можете условно отображать ошибки. (Поскольку это пример, не имеет значения, что вы вводите в форму — нажмите «Отправить», чтобы сделать запрос, который будет 404 и обновить состояние с ошибкой).
class Example extends React.Component {
constructor (props) {
super(props)
this.state = {errors: []}
}
setErrors = (...errors) => {
this.setState({errors})
}
submitForm = () => {
// intentionally return a 404 as an example
// change to false to mock a valid ajax request
const hasError = true
axios.get(`https://jsonplaceholder.typicode.com/${
hasError ? 'fake' : 'todos/1'}`)
.then(() => {
this.setErrors()
})
.catch(() => {
this.setErrors('Invalid Email Or Password')
})
}
render () {
return (
<div>
<div style={{color: 'red'}}>
{this.state.errors.map(e => <div>{e}</div>)}
</div>
<div><label>Email<input type="email" /></label></div>
<div><label>Password<input type="password" /></label></div>
<button type="button" onClick={this.submitForm}>Submit</button>
</div>
)
}
}
ReactDOM.render(<Example />, document.querySelector('#app'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.js"></script>
<div id="app"></div>
Комментарии:
1. Действительно спасибо! Был идеальным ответом. Теперь я получаю немного лучшее представление о том, как работать с dom в react, и это делается в моем коде. Спасибо!
Ответ №2:
Вам необходимо установить информацию об ошибке в состояние при обнаружении сбоя API, затем в функции рендеринга, если обнаружено состояние ошибки, вы можете соответствующим образом отобразить html-код сообщения об ошибке. мы можем написать любой javascript в рендеринге, прежде чем возвращать jsx.
import *;
class App extends Component {
state={
data: null,
loading: false,
errorMessage: ''
}
handleSubmit = e => {
e.preventDefault();
const user = {
usuario: this.usuario.value,
contraseña: this.password.value
};
axios.post(`http://api`, user).then(res => {
this.setState({
data: res.data,
loading: true
});
if (Object.keys(res.data).length > 0) {
alert("LOGIN");
this.setState({
errorMessage: ''
});
} else {
this.setState({
errorMessage: 'Bad Login details'
});
alert("NOT LOGIN");
}
console.log(res.data);
});
}
render() {
let errorMessageHtml;
if(this.state.errorMessage){
errorMessageHtml = <p>{this.state.errorMessage}</p>
}
return (
<Container>
<Form onSubmit={this.handleSubmit}>
<Row>
<Col md="4"> </Col>{" "}
<Col md="4">
<Card>
<CardBody>
<FormGroup>
<InputGroup>
<InputGroupAddon addonType="append">
<InputGroupText>
<FontAwesomeIcon icon={faUser} />{" "}
</InputGroupText>{" "}
</InputGroupAddon>{" "}
<Input
placeholder="Usuario"
type="text"
innerRef={element => {
this.usuario = element;
}}
/>{" "}
</InputGroup>{" "}
</FormGroup>
<FormGroup>
<InputGroup>
<InputGroupAddon addonType="append">
<InputGroupText>
<FontAwesomeIcon icon={faKey} />{" "}
</InputGroupText>{" "}
</InputGroupAddon>{" "}
<Input
placeholder="Password"
type="password"
innerRef={element => {
this.password = element;
}}
/>{" "}
</InputGroup>{" "}
</FormGroup>
<Row>
<Col md="8"> </Col>{" "}
<Col md="4">
<Button color="success"> Login </Button>{" "}
</Col>{" "}
</Row>{" "}
</CardBody>{" "}
</Card>{" "}
</Col>{" "}
<Col md="4"> </Col>{" "}
</Row>{" "}
{errorMessageHtml}
</Form>
</Container>
);
}
}
export default App;
Комментарии:
1. Я получаю сообщение об ошибке: TypeError: this.state равно нулю. В if(this.state.ErrorMessage). Это что-то похожее, я не знаю почему, но не могу получить значение чего-либо вне рендеринга.
2. Я забыл добавить объект состояния в класс, прежде чем обращаться к нему, пожалуйста, проверьте обновленный код.