Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Call selector function from React Component?

This is my Selector , I can able to get data with in the selector but don't know how to call this into view (Component) ,

import {todos} from '../reducers/todos';
import { createSelector } from 'reselect'
var visibilityFilter='SHOW_ALL';

var getVisibilityFilter = (state) =>  visibilityFilter;
var getTodos = (state) => todos;

export const getVisibleTodos = createSelector(
  [ getVisibilityFilter, getTodos ],
  (visibilityFilter, todos) => {


    switch (visibilityFilter) {
      case 'SHOW_ALL':
        return todos
      case 'SHOW_COMPLETED':
        return todos.filter(t => t.completed)
      case 'SHOW_ACTIVE':
        return todos.filter(t => !t.completed)
    }


  }  
)

export default getVisibleTodos;

I have Tried in Component

<button onClick={()=>props.getVisibleTodos(props.SHOW_ALL , props.experimentData.lights)}> SHOW_COMPLETED</button>

Error

Uncaught Error: Actions must be plain objects. Use custom middleware for async actions. Blockquote

Help me Out ...

like image 240
Gopinath Kaliappan Avatar asked Sep 18 '25 11:09

Gopinath Kaliappan


2 Answers

You should call the selector on the connect function like this:

import { connect } from 'react-redux';
import getVisibleTodos from 'your/selector/file';

function YourComponent({ visibleTodos }) {
  // You can access visibleTodos inside your component
  // because now it's on the props

  return (
    <div>
      //...
    </div>
  );
}

const mapping = (state, props) => ({
  visibleTodos: getVisibleTodos(state, props),
});

connect(mapping)(YourComponent);

Inside the mapping function, you have access to the state and props for the current component. Keep in mind that all selectors must receive the redux store in order to query the data.

Good luck!

like image 75
Crysfel Avatar answered Sep 20 '25 02:09

Crysfel


I expect that your Redux store state looks something like this:

{
  todos: [
    {
      id: 1,
      text: 'Buy milk',
      completed: false
    },
    ...
  ],
  visibilityFilter: 'SHOW_ALL'
}

If it is so, then you have to rewrite your getVisibilityFilter and getTodos selectors.

const getVisibilityFilter = (state) => state.visibilityFilter;

const getTodos = (state) => state.todos;

Previously you weren't accessing the values from your state, using this edited functions you are. See how I am using dot notation to access the keys of state, which is nothing more than a JavaScript Object.

Also, when u want to use a selector, you should use it in a container component, where u can access the store's state using mapStateToProps function.

The container could look something like this:

import React from 'react';
import { connect } from 'react-redux';
import { getVisibleTodos } from './selectors.js';
import TodosList from './TodosList.jsx';

const mapStateToProps = (state) => {
  return {
    todos: getVisibleTodos(state)
  }
}

const VisibleTodosList = connect(
  mapStateToProps
)(TodosList);

export default VisibleTodosList;

Where the TodosList component is your own component that displays the todos. It will receive all visible todos using props (this.props.todos).

In my opinion, selectors aren't called from your view (presentational) components, they are meant to be used in containers, where you can access the application's data.

If you want to learn more about containers and presentational components, take a look at this article, it's worth reading.

like image 32
vasekhlav Avatar answered Sep 20 '25 00:09

vasekhlav