我要做的是,如果输入值与API调用中的任何电影都不匹配,则将输入的边框更改为红色。 用户在输入字段中键入,对API的调用将显示匹配结果。 如果没有任何结果,我希望输入的边框为红色。 但是我看不到我该如何实现。
Input组件位于代码段的末尾。
CSS
.input-style {
padding: 7px;
border-radius: 5px;
border: 1px solid #cccccc;
font-family: Courier New, Courier, monospace;
transition: background-color 0.3s ease-in-out;
outline: none;
}
.input-style:focus {
border: 1px solid turquoise;
}
APP.js
class App extends Component {
constructor() {
super();
this.state = {
value: '',
items: [],
isLoading: false,
searchResult: null,
error: false,
};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
// To handle search
handleChange(e) {
this.setState({ value: e.target.value });
}
handleSubmit(e) {
let searchResult = [];
for (var i = 0; i < this.state.items.length; i++) {
if (
this.state.items[i].name
.toLowerCase()
.indexOf(this.state.value.toLowerCase()) !== -1
) {
searchResult.push(this.state.items[i]);
} else {
console.log('No matches on your search, try again');
}
}
e.preventDefault();
// If we have something in the object searchResult
if (searchResult.length > 0) {
this.setState({
error: false,
value: '',
searchResult: searchResult,
});
} else {
this.setState({
error: true,
value: '',
searchResult: [],
});
}
}
// call to the API
componentDidMount() {
this.setState({ isLoading: !this.state.isLoading });
fetch('https://api.tvmaze.com/shows')
.then(response => response.json())
.then(data => {
this.setState({
items: data,
error: false,
});
this.setState({ isLoading: !this.state.isLoading });
})
.catch(console.error);
}
render() {
return (
<div className="App">
<Header />
<Loader isLoading={this.state.isLoading} />
<Input
handleChange={this.handleChange}
handleSubmit={this.handleSubmit}
value={this.state.value}
/>
{this.state.error ? (
<p className="errorMsg">No match on the search, try again!</p>
) : null}
<Search search={this.state.searchResult} />
</div>
);
}
}
export default App;
Input.js
function Input(props) {
return (
<div>
<form onSubmit={props.handleSubmit}>
<input
type="text"
className="input-style"
placeholder="Sök efter film.."
value={props.value}
onChange={props.handleChange}
/>
<button id="bold" className="button-style" type="submit">
<i className="fa fa-search" />
</button>
</form>
</div>
);
}
export default Input;
答案 0 :(得分:3)
您可以将错误从Input
传递到App
组件中
<Input
handleChange={this.handleChange}
handleSubmit={this.handleSubmit}
value={this.state.value}
error={this.state.error)
/>
并在您的Input
组件中:
<input
type="text"
className={props.error ? 'error-input-style' : 'input-style'}
placeholder="Sök efter film.."
value={props.value}
onChange={props.handleChange}
/>
或者,您也可以为错误条件设置内联样式:
<input
type="text"
className="input-style"
placeholder="Sök efter film.."
value={props.value}
onChange={props.handleChange}
style={{ border: props.error ? '1px solid red' : '' }}
/>
答案 1 :(得分:1)
您可以轻松地做到这一点。在状态resultFound
中有另一个像App
的键,其初始值为null或false。然后在使API调用结果的函数中,检查是否获得了任何结果,然后使用this.setState({resultFound: //true or false accordingly})
在此更新状态。为错误创建CSS类,例如
.inputError {
border: 1px solid red;
}
然后在返回之前在render方法中,为className创建一个变量,如
let inputClassName = '';
if(this.state.resultFound===false){
inputClassName = 'inputError';
}else{
inputClassName = 'input-style';
}
然后将状态值作为道具传递给Input
之类的customStyle={inputClassName}
组件,并将其作为输入元素的类名,例如
<input type="text" className={props.customStyle} ... />
因此,每当API调用发生时,您的状态就会更改,从而导致DOM的重新渲染,并且render方法每次都会被调用。在每次呼叫时,都会检查resultFound
的状态,并相应地将className
应用于输入字段。
答案 2 :(得分:1)
我将为类和变量起坏名字,只是为了使其非常清晰。您应该使用更通用的。
这里的窍门是通过道具为Input提供一个动态类,如果该表达式变为true,并且该类已附加到元素上,则可以使用css对其进行样式设置。
__CSS__
.input-style {
padding: 7px;
border-radius: 5px;
border: 1px solid #cccccc;
font-family: Courier New, Courier, monospace;
transition: background-color 0.3s ease-in-out;
outline: none;
}
.input-style:focus {
border: 1px solid turquoise;
}
.input-style.red-border {
border: 1px solid red;
}
__APP.js__
class App extends Component {
constructor() {
super();
this.state = {
value: '',
items: [],
isLoading: false,
searchResult: null,
error: false,
};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
// To handle search
handleChange(e) {
this.setState({ value: e.target.value });
}
handleSubmit(e) {
let searchResult = [];
for (var i = 0; i < this.state.items.length; i++) {
if (
this.state.items[i].name
.toLowerCase()
.indexOf(this.state.value.toLowerCase()) !== -1
) {
searchResult.push(this.state.items[i]);
} else {
console.log('No matches on your search, try again');
}
}
e.preventDefault();
// If we have something in the object searchResult
if (searchResult.length > 0) {
this.setState({
error: false,
value: '',
searchResult: searchResult,
});
} else {
this.setState({
error: true,
value: '',
searchResult: [],
});
}
}
// call to the API
componentDidMount() {
this.setState({ isLoading: !this.state.isLoading });
fetch('https://api.tvmaze.com/shows')
.then(response => response.json())
.then(data => {
this.setState({
items: data,
error: false,
});
this.setState({ isLoading: !this.state.isLoading });
})
.catch(console.error);
}
render() {
return (
<div className="App">
<Header />
<Loader isLoading={this.state.isLoading} />
<Input
handleChange={this.handleChange}
handleSubmit={this.handleSubmit}
value={this.state.value}
showRedBorder={this.state.error === true} // or what ever your logic
/>
{this.state.error ? (
<p className="errorMsg">No match on the search, try again!</p>
) : null}
<Search search={this.state.searchResult} />
</div>
);
}
}
export default App;
__Input.js__
function Input(props) {
return (
<div>
<form onSubmit={props.handleSubmit}>
<input
type="text"
className={`input-style${props.showRedBorder ? ' red-border' : ''}`}
placeholder="Sök efter film.."
value={props.value}
onChange={props.handleChange}
/>
<button id="bold" className="button-style" type="submit">
<i className="fa fa-search" />
</button>
</form>
</div>
);
}
export default Input;