Redux过滤阵列

时间:2019-12-04 07:35:13

标签: reactjs redux

我已经阅读了类似的问题,但仍然无法弄清楚。当我键入内容时,它会过滤掉屏幕上的项目,但是如果我在搜索框中删除一个字符,它将不会显示以前的项目。例如,我键入“ ab”会显示所有以“ ab”开头的产品名称,但是,当我删除“ b”或“ ab”时,它不会显示产品,只会显示一个空白页。

搜索

class Search extends Component {
  handleChange = e => {
    this.props.search(e.target.value);
  };

  render() {
    return (
      <>
        <Input
          type="search"
          name="search"
          placeholder="Search"
          onChange={this.handleChange}
          value={this.props.value}
        />
      </>
    );
  }
}

const mapStateToProps = state => ({
  value: state.value
});

export default connect(mapStateToProps, { search })(Search);

动作

export const search = value => ({
  type: SEARCH,
  payload: value
});

减速器

export const Products = (
  state = {
    products: [],
    comments: [],
    value: ''
  },
  action
) => {
  switch (action.type) {
    ...
    case 'SEARCH':
      return {
        ...state,
        value: action.payload,
        products: state.products.filter(product => product.name.includes(action.payload))
      };
    default:
      return state;
  }
};

2 个答案:

答案 0 :(得分:0)

每次过滤时,您都在更新products的状态,因此每次连续搜索都针对先前过滤的值。换句话说,您将丢失products数组的原始副本。

您只需要存储搜索值,然后预订products的任何组件都可以从搜索值中获取过滤后的产品。例如:

class Example extends Component {
  render() {
    const filteredProducts = this.props.products.filter(product =>
      product.name.includes(this.props.value)
    );
    return filteredProducts.map(product => ...)
  }
}

const mapStateToProps = state => ({
  value: state.value,
  products: state.products,
});

export default connect(mapStateToProps, { search })(Example);

答案 1 :(得分:0)

尽管,@ wrsx的答案是解决根本原因并提出适当的解决方案,但我可能会根据接受的评论认为,可能会引起某些混淆(由于缺乏经验,这是可能的原因之一)。答案。

因此,在提炼出带有扩展注释的示例之后,对于那些希望构建相同功能的人可能会派上用场。

需要指出的是,此问题的根本原因是在搜索时更新商店,并使用过滤后的副本设置保存产品数组的状态变量,这就是为什么以后无法从过滤后的数组中获得更广泛的搜索结果的原因。

要解决此问题,reduce程序必须不要修改初始数组,而是存储搜索到的字符串,以便其他组件(尤其是from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler from keras.models import Sequential from keras.layers import Dense, Dropout, Activation import pandas as pd _data = pd.read_csv('breast-cancer-wisconsin.data') _data_new = _data.drop(['1000025'],axis=1) X = _data_new.iloc[:,0:8] Y = _data_new.iloc[:,9] X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size = 0.25, random_state = 42) sc = StandardScaler() X_train = sc.fit_transform(X_train) X_test = sc.transform(X_test) model = Sequential() model.add(Dense(8, input_dim=8)) model.add(Activation("relu")) model.add(Dropout(0.1)) model.add(Dense(64)) model.add(Activation("relu")) model.add(Dropout(0.1)) model.add(Dense(32)) model.add(Activation("relu")) model.add(Dropout(0.1)) model.add(Dense(1)) model.add(Activation("relu")) model.compile(loss='mae', optimizer='sgd', metrics=['accuracy']) predictions = model.predict(X_test[:])#predictions before training of the model print('predictions shape:', predictions) model.fit(X_train, Y_train, epochs=500, batch_size= 10, validation_split=0.12) test_loss, test_acc = model.evaluate(X_test, Y_test) print('\nTest loss:', test_loss) print('Test accuracy:', test_acc) predictions = model.predict(X_test[:])#predictions after training of the model print('predictions shape:', predictions) )可以访问它:

appReducer.js

ProductList

在搜索时,只有状态变量const appReducer = (state = defaultState,action) => { switch(action.type){ case 'SEARCH_PRODUCT': { const searchedString = action.payload return {...state, searchedString} } default: return state } } 应该被更新:

SearchBar容器组件(/containers/searchBar.js)

searchedString

SearchBar ui组件(/ui/searchBar.js)

const mapDispatchToProps = dispatch => ({
        onSearch: searchedString => dispatch({type:'SEARCH_PRODUCT', payload:searchedString})
      }),
      Container = connect(null,mapDispatchToProps)(SearchBar)

与此同时,const SearchBar = ({onSearch}) => ( <input onKeyUp={e => onSearch(e.target.value)}></input> ) 组件应根据ProductListfilteredList存储变量来获得其productList属性:

ProductList容器组件(/containers/productList.js)

searchedString

ProductList用户界面组件(/ui/productList.js)

const mapStateToProps = ({searchedString,productList}) => ({
        filteredList: productList.filter(item => item.toLowerCase().includes(searchedString.toLowerCase()))
      }),
      Container = connect(mapStateToProps)(ProductList)

您可以通过以下组合演示来研究这种方法:

const ProductList = ({filteredList}) => (
  <ul>
    {filteredList.map((item,key)=><li key={key}>{item}</li>)}
  </ul>
)
//dependencies
const React = React,
      { render } = ReactDOM, 
      { createStore } = Redux, 
      { connect, Provider } = ReactRedux

//store initialization
const	defaultState = {
			"searchedString": "",
			"productList": [
				"productA",
				"productB",
				"productC",
				"productD",
				"some other stuff"
			]
		},
		appReducer = (state = defaultState, action) => {
			switch (action.type) {
			case 'SEARCH_PRODUCT': {
					const searchedString = action.payload
						return {
						...state,
						searchedString
					}
				}
			default:
				return state
			}
		},
		store = createStore(appReducer)
//components
const	ProductList = ({filteredList}) => (
			 <ul> 
				{filteredList.map((item, key) =>  <li key = {key}> {item} </li>)}
			 </ul>
		),
		SearchBar = ({onSearch}) => (
			<input onKeyUp = {e => onSearch(e.target.value)}></input>
		)
//containers
const mapStateToProps = ({searchedString, productList}) => ({
	filteredList: productList.filter(item => item.toLowerCase().includes(searchedString.toLowerCase()))
})
const ProductListContainer = connect(mapStateToProps)(ProductList)
const mapDispatchToProps = dispatch => ({
	onSearch: searchedString => dispatch({
		type: 'SEARCH_PRODUCT',
		payload: searchedString
	})
})
const SearchBarContainer = connect(null, mapDispatchToProps)(SearchBar)
//provider wrapper
render(
	 <Provider store = {store}>
		 <SearchBarContainer />
		 <ProductListContainer />
	 </Provider>,
	document.getElementById('root')
)