Nicu Ionut Campian
Nicu Ionut Campian

Reputation: 49

Material UI TextField React Component Conditional style don't trigger textField render

React Component :

class Info extends Component {
    constructor() {
       this.state = {
        editAccount: false
       }
       this.changeTrue = this.changeTrue.bind(this);
       this.changeFalse = this.changeFalse.bind(this);
    }
    changeTrue() {
      this.setState({ediAccount: true}
    }
    changeFalse() {
      this.setState({ediAccount: false}
    }
    render() {
        const specific_style = this.state.editAccount ? { background: 'red'} : { background : 'yellow' }
        return (
         <div>
            <TextField
                id='first_name'
                inputStyle={ specific_style}
                value={this.state.first_name}
              />
           <button onClick={this.changeTrue}>Click True</button>
           <button onClick={this.changeFalse}>Click False</button>
         </div>
        )
    }
}

Having this component and editAccount having the state changed doesn't rerender apply the style changes? Doesn't rerender the TextField ? Anybody knows why ?

Upvotes: 1

Views: 7407

Answers (4)

trixn
trixn

Reputation: 16354

State Updates May Be Asynchronous

React may batch multiple setState() calls into a single update for performance.

Because this.props and this.state may be updated asynchronously, you should not rely on their values for calculating the next state.

When updating the state based on the current state always use a callback in the call to setState(). The callback gets the previous state and returns the next state. This is because react may batch multiple calls to setState() thus not using a callback will override previous calls:

this.setState(prevState => ({editAccount: !prevState.editAccount)});

Also in your object that contains the styles you used variables (which you did not define) instead of strings:

const specific_style = this.state.editAccount ? { background: red /* red is not defined*/} : { background : yellow /* same here */ };

It should probably be:

const specific_style = this.state.editAccount ? { background: 'red' } : { background : 'yellow' };

Objects can't be written like css classes.

The fully working code has to look about like this:

class Info extends Component {
  constructor(props) {
    super(props);

    this.state = {
      editAccount: false
    };

    this.changeStyle = this.changeStyle.bind(this);
  }

  changeStyle() {
    this.setState(state => ({editAccount: !state.editAccount}));
  }

  render() {
    const specific_style = this.state.editAccount ? { background: 'red' } : { background: 'yellow' };
    return (
      <div>
        <TextField
          id="first_name"
          inputStyle={specific_style}
        />
        <button onClick={this.changeStyle}>Toggle red/yellow</button>
      </div>
    );
  }
}

See this working codesandbox example.

Upvotes: 1

Victor Baron
Victor Baron

Reputation: 177

Where / How is editAccount defined ? It should come from the state or the props to trigger the re-render.

If the render() method isn't affected by the props / state changes, it isn't triggered.

Upvotes: 0

Christopher Mellor
Christopher Mellor

Reputation: 444

You may need to use a lifecycle method like componentWillReceiveProps to force a re-render. Also - format your code

Upvotes: 0

Joshua Underwood
Joshua Underwood

Reputation: 927

It appears you forgot to put '<' and '/>' within the return of your render function. Two of us made edits to resolve this but perhaps thats also the issue

Upvotes: 0

Related Questions