React + Material UI - Textfield "onChange" never fired

15,742

Do these changes:

1. Bind the method in Parent component LinkList, because you are using this.setState inside onChange method, if you don't bind it, it will throw the error, bind it like this:

<SearchLink onChange={this._onChange.bind(this)} value={this.state.inputValue}/>

or define the binding in constructor.

2. You are passing the event and value in props, so you need to define those values in TextField, like this:

const SearchLink = (props) => (
    <MuiThemeProvider muiTheme={muiTheme}>
        <TextField 
             onChange = {props.onChange} 
             value = {props.value} 
             floatingLabelText = "Search a Link" 
             name = "searchLink" 
             fullWidth = {true}/>
    </MuiThemeProvider>
);
Share:
15,742
Admin
Author by

Admin

Updated on June 15, 2022

Comments

  • Admin
    Admin almost 2 years

    I've tried to fire an onchange function when my Textfield is filled, but i can't figure out why this function is never fired, even if React devtool plugin for Chrome actually trigger the changes, any advice ?

    import React, {Component} from 'react';
    import {Tracker} from 'meteor/tracker';
    import {Meteor} from 'meteor/meteor';
    import {Links} from '../api/links';
    import LinkListItem from './LinkListItem';
    import {Session} from 'meteor/session';
    import SearchLink from './SearchLink';
    import Fuse from 'fuse.js';
    
    export default class LinkList extends Component {
        constructor(props) {
            super(props);
            this.state = {
                links: [],
                inputValue: ''
            };
        }
        componentDidMount() {
            this.linksTracker = Tracker.autorun(() => {
                Meteor.subscribe('links');
    
                const links = Links.find({visible: 
                Session.get('showVisible')}).fetch();
                this.setState({links});
            });
        }
        componentWillUnmount() {
            this.linksTracker.stop();
        }
        renderLinksListItems() {
            if (this.state.links.length === 0) {
                    return (
                        <div>
                            <h2 className="link">{Session.get('showVisible') ? 'No links found' : 'No hidden links found'}</h2>
                        </div>
                    );
            }
            console.log(this.state.links);
            return this.state.links.map((link) => {
                const shortUrl = Meteor.absoluteUrl(link._id);
                return <LinkListItem key={link._id} shortUrl={shortUrl} {...link}/>;
            });
        }
        _onChange(e) {
            if(e.target.value === "") {
                return;
            }
            var fuse = new Fuse(this.state.links, { keys: ["url"]});
            var result = fuse.search(e.target.value);
            this.setState({
                inputValue: e.target.value,
                links: result
            });
        }
        render() {
            return (
                <div>
                  <div>
                      <SearchLink onChange={this._onChange} value={this.state.inputValue}/>
                  </div>
                  <div>{this.renderLinksListItems()}</div>
                </div>
            );
        }
    }
    

    My Textfield component :

    import React from 'react';
    import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
    import getMuiTheme from 'material-ui/styles/getMuiTheme';
    import TextField from 'material-ui/TextField';
    
    const muiTheme = getMuiTheme({
      palette: {
          primary1Color: '#ef6c00'
      }
    })
    
    const SearchLink = () => (
      <MuiThemeProvider muiTheme={muiTheme}>
        <TextField floatingLabelText="Search a Link" name="searchLink" fullWidth={true}/>
      </MuiThemeProvider>
    );
    
    export default SearchLink;
    

    Thank you for your help!