user11066242
user11066242

Reputation: 233

Function not working on onClick event in React.js

I am writing a react program where data will be fetched through an API and will be displayed in a table. There are 3 main files App.js, Table.js and Search.js and Button.js. The data is being displayed, the search is working but delete button is not working. I have written a function for delete button and I guess something is wrong in that but don't know what.

App.js

import React, { Component } from 'react';
import './App.css';
import Table from './components/Table';
import Search from './components/Search';


//API config
const DEFAULT_QUERY = 'react';
const PATH_BASE = 'https://hn.algolia.com/api/v1';
const PATH_SEARCH = '/search';
const PARAM_SEARCH = 'query=';

const url = `${PATH_BASE}${PATH_SEARCH}?${PARAM_SEARCH}${DEFAULT_QUERY}`;


class App extends Component {
  constructor(){
    super();
    //here searchText is set to DEFAULT_QUERY which will return the result for keyword "redux"
    //refer line 8 to change
    this.state={
      searchText:'',
      result:''
    }
    this.onDismiss=this.onDismiss.bind(this);
    this.onSearchChange=this.onSearchChange.bind(this);
    this.searchStories=this.searchStories.bind(this);

    //this.isSearched=this.isSearched.bind(this);
  }

  //to add a delete button
  onDismiss=(id)=>{
    //filter out item array and return results with no matched id
    const deleteList=this.state.list.filter(item=>item.objectID!==id);
    //setting state of list to lastest deleteList
    this.setState({
      result:deleteList
    })  
  }
  //to add a search bar
  onSearchChange=(e)=>{
    //set state to value in search bar
    this.setState({
      [e.target.name]:e.target.value
    })
  }

  searchStories=(result)=>{
    this.setState({
      result
    });
  }
  //after mounting will fetch the api data
  componentDidMount(){
    fetch(url)
    .then(response => response.json())
    .then(result => this.searchStories(result));
  }

  render() {
    const {result,searchText}=this.state;
    if(!result){
      return null;
    }
    return(
      <div className="page">
          <div className="interactions">

        <Search
       searchText={searchText}
       onSearchChange={this.onSearchChange}
       >
        Search
        </Search>
        </div>
       <Table
       list={result.hits}
       onDismiss={this.onDismiss}
       searchText={searchText}/>

      </div>

    )

  }
}

export default App;

Table.js

import React from 'react';
import Button from './Button';

const Table=(props)=>{
    const {list,searchText,onDismiss}=props;
    return(
        <div className="table">

       {/*Filter out item title and search title and give away results from item array */}
        {list.filter((item)=>{
          {/*The includes() method determines whether an array includes a certain value among its entries
          , returning true or false as appropriate. */}
          return item.title.toLowerCase().includes(searchText.toLowerCase());}).map((item)=>{

            return(

            <div key={item.objectID} className="table-row">
                  <span style={{ width: '40%' }}>
                        <a href={item.url}>{item.title}</a>
                        </span>
                        <span style={{ width: '30%' }}>
                        {item.author}
                        </span>
                        <span style={{ width: '10%' }}>
                        {item.num_comments} comments
                        </span>
                        <span style={{ width: '10%' }}>
                        ${item.points} points
                        </span>
                        <span style={{ width: '10%' }}>
                  <Button className="button-inline" onClick={()=>onDismiss(item.objectID)}>delete</Button>
                  </span>

            </div>

          )})}
      </div>
    )

  }


export default Table;

Button.js

import React from 'react';

const Button=(props)=>{

    const{onclick,className='',children}=props;
    return(
      <div>
          <button onClick={onclick} className={className} >{children}</button>
      </div>
    )

  }


export default Button;

Upvotes: 0

Views: 1794

Answers (2)

Muljayan
Muljayan

Reputation: 3886

In Button component change

const{onclick,className='',children}=props;

to

const{onClick,className='',children}=props;

Also it seems that you have not set list in the state therefore when you try to access this.state.list.filter it will throw an error.

onDismiss=(id)=>{    
  const deleteList=this.state.result.hits.filter(item=>item.objectID!==id);    
  this.setState({
  result:{...this.state.result,hits:deleteList}
})  

}

Upvotes: 1

rrd
rrd

Reputation: 5957

Your button needs to be modified slightly:

<button onClick={onClick} className={className} >{children}</button>

The handler needs to refer to the props passed in which are this.props.onClick, not this.props.onclick (which you had).

The error you are encountering can be fixed by modifying the App.js:

onDismiss = id => {
  if (id) {
    const deleteList = this.state.list.filter(item => item.objectID !== id);
    // setting state of list to lastest deleteList
    this.setState({
      result:deleteList
    }) 
  }
}

Upvotes: 2

Related Questions