Javascript 反应-在一个特定状态下更改css样式

Javascript 反应-在一个特定状态下更改css样式,javascript,css,reactjs,Javascript,Css,Reactjs,我想做的是,如果输入值与API调用中的任何电影不匹配,则将输入上的边框更改为红色。 用户在输入字段中键入,对API的调用显示匹配结果。 如果我们没有任何结果,我希望输入的边框是红色的。 但我不知道我该怎么做 组件输入位于代码段的末尾 CSS .input-style { padding: 7px; border-radius: 5px; border: 1px solid #cccccc; font-family: Courier New, Courier, monospace;

我想做的是,如果输入值与API调用中的任何电影不匹配,则将输入上的边框更改为红色。 用户在输入字段中键入,对API的调用显示匹配结果。 如果我们没有任何结果,我希望输入的边框是红色的。 但我不知道我该怎么做

组件输入位于代码段的末尾

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;
类应用程序扩展组件{
构造函数(){
超级();
此.state={
值:“”,
项目:[],
孤岛加载:false,
搜索结果:null,
错误:false,
};
this.handleChange=this.handleChange.bind(this);
this.handleSubmit=this.handleSubmit.bind(this);
}
//处理搜索
手变(e){
this.setState({value:e.target.value});
}
handleSubmit(e){
让searchResult=[];
对于(var i=0;i0){
这是我的国家({
错误:false,
值:“”,
searchResult:searchResult,
});
}否则{
这是我的国家({
错误:正确,
值:“”,
搜索结果:[],
});
}
}
//调用API
componentDidMount(){
this.setState({isLoading:!this.state.isLoading});
取('https://api.tvmaze.com/shows')
.then(response=>response.json())
。然后(数据=>{
这是我的国家({
项目:数据,
错误:false,
});
this.setState({isLoading:!this.state.isLoading});
})
.catch(控制台错误);
}
render(){
返回(
{this.state.error(

搜索结果不匹配,请重试

):null} ); } } 导出默认应用程序;
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;
功能输入(道具){
返回(
);
}
导出默认输入;

您可以从
应用程序

<Input
   handleChange={this.handleChange}
   handleSubmit={this.handleSubmit}
   value={this.state.value}
   error={this.state.error)
/>
或者,也可以为错误条件设置内联样式:

 <input
   type="text"
   className="input-style"
   placeholder="Sök efter film.."
   value={props.value}
   onChange={props.handleChange}
   style={{ border: props.error ? '1px solid red' : '' }}
 />

您可以轻松做到这一点。在
App
class的状态下使用另一个键,如
resultFound
,其初始值为null或false。然后在对结果进行API调用的函数中,检查是否获得了任何结果,然后使用
this.setState({resultFound://true或false})
更新那里的状态。为错误创建一个CSS类,比如

.inputError {
  border: 1px solid red;
}
然后在return之前的render方法中,为类名创建一个变量,如

let inputClassName = '';
if(this.state.resultFound===false){
  inputClassName = 'inputError';
}else{
  inputClassName = 'input-style';
}
然后将此状态值作为prop传递给
Input
组件,如
customStyle={inputClassName}
,并将其指定为输入元素的类名,如

<input type="text" className={props.customStyle} ... />


因此,每当API调用发生时,您的状态都会更改,从而导致DOM的重新呈现,并且每次都会调用render方法。每次调用时,都会检查状态是否为
resultFound
,相应地,
className
将应用于输入字段。

我将为类和变量指定错误的名称,只是为了让它非常清楚。你应该使用更通用的

这里的技巧是通过props为您的输入提供一个动态类,如果该表达式变为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;
\uu CSS__
.输入方式{
填充:7px;
边界半径:5px;
边框:1px实心#中交;
字体系列:Courier New、Courier、monospace;
过渡:背景色0.3s缓进缓出;
大纲:无;
}
.输入方式:焦点{
边框:1px纯绿松石色;
}
.input-style.red-border{
边框:1px纯红;
}
__APP.js_uu
类应用程序扩展组件{
构造函数(){
超级();
此.state={
值:“”,
项目:[],
孤岛加载:false,
搜索结果:null,
错误:false,
};
this.handleChange=this.handleChange.bind(this);
this.handleSubmit=this.handleSubmit.bind(this);
}
//处理搜索
手变(e){
this.setState({value:e.target.value});
}
handleSubmit(e){
让searchResult=[];
对于(var i=0;i0){
这是我的国家({
错误:false,
值:“”,
searchResult:searchResult,
});
}否则{
这是我的国家({
错误:正确,
值:“”,
搜索结果:[],
});
}
}
//调用API
componentDidMount(){
this.setState({isLoading:!this.state.isLoading});
取('https://api.tvmaze.com/shows')
.then(response=>response.json())
。然后(数据=>{
这是我的国家({
项目:数据,
错误:false,
});
this.setState({isLoading:!this.state.isLoading});
})
C
__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;