javascriptreactjsreduxstoreredux-actions

What is preventing my redux actions from working properly?


I'm a beginner with React so bear with me please. I've been struggling trying to figure this thing out for a few hours now and just can't understand what am I doing wrong.

Everything works just find and loads with 0 errors. But, when I try to launch an action absolutely nothing happens. I am logging the state and there just no extra logs after the initial start of the application.

So what I am trying to build is super simple practice app. It just has a word on the screen, and each letter is a component for itself. The user can click on either of two buttons, to add a letter either in the beginning of the word or at its end. That's it. The only 2 actions I have are for adding these letters.

This is my main App.js:

import React from 'react';
import Header from './Header';
import Adder from './Adder';
import CurrentWord from './CurrentWord';
import { connect } from 'react-redux';
import { addLetterStart, addLetterEnd } from '../actions';

class App extends React.Component {

    render() {
        console.log(this.props.word);
        return (
            <div>
                <Header />
                <div style={{ margin: "100px", display: "flex", justifyContent: "center"}}>
                    <Adder onClick={()=> this.props.addLetterStart()} />
                    <CurrentWord />
                    <Adder onClick={()=> this.props.addLetterEnd()} />
                </div>
            </div>
        )
    }
};

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

export default connect(mapStateToProps, {addLetterStart, addLetterEnd})(App);

This is my CurrentWord component:

import React from 'react';
import SingleLetter from './SingleLetter'
import { connect } from 'react-redux';


class CurrentWord extends React.Component {
    renderLetters() {
        return this.props.word.map(letter => {
            return <SingleLetter key={Math.floor(Math.random() * 100)} letter={letter} />
        });

    }

    render() {
        return (
            <div style={{ display: "flex" }}>
                {this.renderLetters()}
            </div>
        )
    }
};

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

export default connect(mapStateToProps)(CurrentWord);

These are my actions (actions/index.js)

import {ADD_END, ADD_START} from './types';


export const addLetterStart = () => {
    return {
        type: ADD_START
    };
};

export const addLetterEnd = () => {
    return {
        type: ADD_END
    };
};

My LettersReducer:

import { ADD_END, ADD_START } from '../actions/types';

export default (state = ['X', 'X', 'X', 'X'], action) => {
    switch (action.type) {
        case ADD_START:
        return ['X', ...state];

        case ADD_END:
        return [...state, 'X'];

        default:
            return state;
    }
};

My reducers/index.js:

import { combineReducers } from 'redux';
import LettersReducer from './LettersReducer';

export default combineReducers({
    word: LettersReducer
});

And my main index.js:

import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { createStore } from 'redux';

import App from './components/App';
import reducers from './reducers';

const store = createStore(reducers);

ReactDOM.render(
    <Provider store={store}>
        <App />
    </Provider>,
    document.querySelector('#root')
);

This is my Adder component:

import React from 'react';

const Adder = () => {

    return (
        <div className="ui card" style={{
            height: "150px",
            width: "150px",
            display: "flex",
            justifyContent: "center",
            alignItems: "center",
            cursor:"pointer",
            margin: "10px"
        }}>
            <p style={{
                fontSize: "80px", 
                color: "#ececec" }}>+</p>
        </div>
    )

};

export default Adder;

I think this should be everything relevant. I'd appreciate any help, thank you!


Solution

  • The problem is that you're adding onClick on your component Adder, but Adder is not a DOM element. You need to forward that prop to something clickable

    import React from 'react';

    const Adder = ({ onClick }) => {
    
        return (
            <div className="ui card" style={{
                height: "150px",
                width: "150px",
                display: "flex",
                justifyContent: "center",
                alignItems: "center",
                cursor:"pointer",
                margin: "10px"
            }}>
                <a onClick={onClick}><p c={style={{
                    fontSize: "80px", 
                    color: "#ececec" }}>+</p></a>
            </div>
        )
    
    };
    
    export default Adder;
    

    If my memory does not fail, you cannot click on a p tag, so you might want to wrap it with an a anchor or a button. Otherwise, you can do it directly on a p