简体   繁体   中英

How to render element conditionally in react

I am using mobx + react setup for this subpage to make a searchable list of users. My list of items is not rendering with if statement. In the solution I am trying to render one of two lists in my subpage. Depending on boolean 'isSearching'. First element should be shown when input field is empty, and second one is when input field has value written. They are same arrays, Only difference between lists arrays are that one of them is filtered.

Code:

 <ul className='items__block'>
    {
        this.props.PeopleStore.people.isSearching = false ?
            (this.props.PeopleStore.people.map(this.person))
        : 
            (this.props.PeopleStore.searchingList.map(this.person))
    }
</ul>

Althought if I remove condition, it works separated:

<ul className='items__block'>
    {
       this.props.PeopleStore.people.map(this.person)
    }
</ul>


<ul className='items__block'>
    {
       this.props.PeopleStore.people.map(this.person)
    }
</ul>

Store file:

 import { runInAction, observable, action, toJS } from 'mobx'; // ES7 compiler import regeneratorRuntime from 'regenerator-runtime'; class PeopleStore { @observable people = []; @observable loading = false; @observable isSearching = false; @observable searchingList = []; // API call loadPeople = async() => { this.loading = true; const response = await fetch('https://randomuser.me/api/?results=71'); const json = await response.json(); runInAction(() => { this.people = json.results; }); this.loading = false; console.log(toJS(this.people)); } // this function is called by onChange event @action.bound filterList = textTyped => { // changing boolean to identify if input is empty or not if (textTyped.target.value.length < 1) { this.isSearching = false; } else { this.isSearching = true; } console.log(this.isSearching); let peoplesNames = []; for (let i = 0; i < this.people.length; i++) { peoplesNames.push(toJS(this.people[i])); } peoplesNames = peoplesNames.filter(function(item) { return item.name.first.toLowerCase().search(textTyped.target.value.toLowerCase()) !== -1 }); this.searchingList = peoplesNames; // tracking both arrays, they both work console.log(toJS(this.searchingList)); console.log(toJS(this.people)); } } export default new PeopleStore();

Component file:

 @inject('showHandler', 'PeopleStore') @observer class PickList extends React.Component { componentWillMount() { this.props.PeopleStore.loadPeople(); } person = ({name, picture}, index) => <li className="items__block--user" key={index} onClick={this.props.PeopleStore.selectPerson}> <img className="user--image" src={picture.medium} alt="face" /> <span className="user--name">{`${name.first} ${name.last}`}</span> </li>; render() { if (this.props.PeopleStore.loading) { return ( <div className="loader"></div> ); } return ( <React.Fragment> <input className="users__block--input" onChange={this.props.PeopleStore.filterList}></input> <ul className='items__block'> { this.props.PeopleStore.people.isSearching = false //checks mobx prop ? (this.props.PeopleStore.people.map(this.person)) : (this.props.PeopleStore.searchingList.map(this.person)) } </ul>

Why is it not working? On page render isSearching prop is set to false and that should effect the if statement as it is.

Issue is here, you are not checking the condition properly:

this.props.PeopleStore.people.isSearching = false

It should be:

this.props.PeopleStore.people.isSearching == false      // notice "=="

See what will happen with = , it will assign the value returned by ternary operator expression to isSearching variable. It will be treated like this:

isSearching = (false? 1: 2);   // isSearching will get a new value, and second expression will get executed always

Check this snippet:

 let b = false; b = false? 1: 2; //b will become 2 console.log('b = ', b);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM