Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React + Material UI - Textfield "onChange" never fired

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!

like image 588
Kaldrogh Avatar asked Apr 11 '17 08:04

Kaldrogh


1 Answers

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>
);
like image 106
Mayank Shukla Avatar answered Oct 22 '22 03:10

Mayank Shukla