Функция не работает при событии onClick в React.js

#javascript #reactjs #ecmascript-6 #react-redux

#javascript #reactjs #ecmascript-6 #реагировать-redux

Вопрос:

Я пишу программу react, в которой данные будут извлекаться через API и отображаться в таблице. Есть 3 основных файла App.js , Table.js и Search.js и Button.js . Данные отображаются, поиск работает, но кнопка удаления не работает. Я написал функцию для кнопки удаления, и я предполагаю, что в этом что-то не так, но не знаю, что.

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;
  

Комментарии:

1. попробуйте изменить onDismiss={this.onDismiss} на onDismiss={() => this.onDismiss}

Ответ №1:

Ваша кнопка нуждается в небольшом изменении:

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

Обработчику необходимо ссылаться на переданные реквизиты, в которых есть this.props.onClick, а не this.props.onclick (который у вас был).

Ошибка, с которой вы столкнулись, может быть исправлена путем изменения 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
    }) 
  }
}
  

Ответ №2:

В изменении компонента кнопки

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

Для

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

Также кажется, что вы не установили list в состояние, поэтому при попытке получить доступ к this.state.list.filter он выдаст ошибку.

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

}

Комментарии:

1. Это onClick вместо onclick , вы допустили опечатку

2. @Treycos это не работает. Это приводит к сбою приложения, выдавая ошибку: TypeError: не удается прочитать свойство ‘filter’ из undefined

3. @user11066242 В коде ` const deleteList=this.state.list.filter(item=>item.ObjectId!==id); ` функции onDismiss вы пытаетесь получить доступ к this.state.list. Откуда берется список? Вы где-то переводите список в состояние

4. @Muljayan понял, попал в точку. Это был старый код, и я не обновлял его в соответствии со значением состояния. Вместо этого я заменил его на result.hits. фильтруйте, и это сработало. Спасибо

5. @user11066242 похоже, что ваша правка по какой-то причине была отменена моей правкой. Попробуйте отредактировать его еще раз.