Why not view updating? - javascript

console.log function in HelloWorld function is showing updated state so why is paragraph in render function not updating? I can't seem to be able to fix render not updating.
Code:
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import {configureStore} from '#reduxjs/toolkit';
var initialState = {value: 0};
function counterReducer(state=initialState,action) {
if(action.type === 'counter/increment') {
return {
...state,
value: state.value + 1
}
} else {
return state;
}
}
const store = configureStore({reducer: counterReducer});
store.dispatch({type: 'counter/increment'});
class Counter extends React.Component {
HelloWorld = () => {
store.dispatch({type: 'counter/increment'});
console.log(store.getState().value);
}
render() {
return (
<div>
<p>{store.getState().value}</p>
<button onClick={this.HelloWorld}>Add</button>
</div>
);
}
}
ReactDOM.render(<Counter />,document.getElementById('root'));

I have to use 'React-Redux' with #ReduxJS/toolkit to get render() function to update webpage. To get ReduxJS/toolkit to update webpage without 'React-Redux'? Answer: You use store.subscribe() function instead, for eg)
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import {configureStore} from '#reduxjs/toolkit';
var initialState = {value: 0};
function counterReducer(state=initialState,action) {
if(action.type === 'counter/increment') {
return {
...state,
value: state.value + 1
}
} else {
return state;
}
}
const store = configureStore({reducer: counterReducer});
class Counter extends React.Component {
HelloWorld = () => {
store.dispatch({type: 'counter/increment'});
console.log(store.getState().value);
}
render() {
return (
<div>
<p id="update"></p>
<button onClick={this.HelloWorld}>Add</button>
</div>
);
}
}
function Two() {
document.getElementById("update").innerHTML = store.getState().value;
}
store.subscribe(Two);
ReactDOM.render(<Counter />,document.getElementById('root'));
More information Why

Here's how to do ReduxJS/toolkit with React-Redux:
import React from 'react';
import ReactDOM from 'react-dom';
import {configureStore} from '#reduxjs/toolkit';
import {Provider,useSelector} from 'react-redux';
var initialState = {value: 0};
function counterReducer(state=initialState,action) {
if(action.type === 'counter/increment') {
return {
...state,
value: state.value+1
};
}
return state;
}
const store = configureStore({reducer: counterReducer});
function Counter() {
function HelloWorld() {
store.dispatch({type: 'counter/increment'});
}
let x = useSelector((state) => state.value);
return (
<div>
<p>{x}</p>
<button onClick={HelloWorld}>Add</button>
</div>
);
}
ReactDOM.render(
<Provider store={store}>
<Counter />
</Provider>,
document.getElementById('root')
);

To do answer the mapStateToProps (old fashioned way)?
import React from 'react';
import ReactDOM from 'react-dom';
import {configureStore} from '#reduxjs/toolkit';
import {Provider,connect} from 'react-redux';
var initialState = {value: 0};
function counterReducer(state=initialState,action) {
if(action.type === 'counter/increment') {
return {
...state,
value: state.value+1
};
}
return state;
}
const store = configureStore({reducer: counterReducer});
function Counter(props) {
function HelloWorld() {
store.dispatch({type: 'counter/increment'});
}
return (
<div>
<p>{props.x}</p>
<button onClick={HelloWorld}>Add</button>
</div>
);
}
const mapStateToProps = (state) => ({
x: state.value
})
Counter = connect(mapStateToProps)(Counter);
ReactDOM.render(
<Provider store={store}>
<Counter />
</Provider>,
document.getElementById('root')
);

How to do mapDispatchToProps?
import React from 'react';
import ReactDOM from 'react-dom';
import {configureStore} from '#reduxjs/toolkit';
import {Provider,connect} from 'react-redux';
var initialState = {value: 0};
function counterReducer(state=initialState,action) {
if(action.type === 'counter/increment') {
return {
...state,
value: state.value+1
};
}
return state;
}
const store = configureStore({reducer: counterReducer});
function Counter(props) {
return (
<div>
<p>{props.x}</p>
<button onClick={props.HelloWorld}>Add</button>
</div>
);
}
const mapStateToProps = (state) => ({
x: state.value
})
const mapDispatchToProps = (dispatch) => ({
HelloWorld: () => {dispatch({type: 'counter/increment'})}
})
Counter = connect(mapStateToProps,mapDispatchToProps)(Counter);
ReactDOM.render(
<Provider store={store}>
<Counter />
</Provider>,
document.getElementById('root')
);

Related

React - mapStateToProps - "state is undefined"

I have the following problem: Using the code below I get the error:
this.props.posts is undefined
As I am following the tutorial https://codeburst.io/redux-a-crud-example-abb834d763c9 an I typed everything correct I am totally confused already at the beginning of my React career. Could you please help me?
import React, { Component } from 'react';
import { connect } from 'react-redux';
import Post from './Post';
class AllPost extends Component {
render() {
return (
<div>
<h1>All Posts</h1>
{this.props.posts.map((post) => <Post key={post.id} post={post} />)}
</div>
);
}
}
const mapStateToProps = (state) => {
return {
posts: state,
}
}
export default connect(mapStateToProps)(AllPost);
Thanks a lot for your efforts!
The following is the postReducer:
const postReducer = (state = [], action) => {
switch(action.type) {
case 'ADD_POST':
return state.concat([action.data]);
default:
return state;
}
}
export default postReducer;
And here the index.js:
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import { createStore } from 'redux';
import { Provider } from 'react-redux';
import postReducer from './reducers/postReducer';
const store = createStore(postReducer);
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>, document.getElementById('root'));
You need to declare an initial state. So your this.props.posts won't be undefined.
const initialState = {
posts: []
}
const postReducer = (state = initialState, action) => {
switch(action.type) {
case 'ADD_POST':
return { ...state, posts: [...state.posts, action.data]}
default:
return state;
}
}
export default postReducer;
The second error is located inside your mapStateToProps method. You need to access to posts redux state key. posts: state.posts like I did below
import React, { Component } from 'react';
import { connect } from 'react-redux';
import Post from './Post';
class AllPost extends Component {
render() {
return (
<div>
<h1>All Posts</h1>
{this.props.posts.map((post) => <Post key={post.id} post={post} />)}
</div>
);
}
}
const mapStateToProps = (state) => {
return {
posts: state.posts, // you need to access to posts key
}
}
export default connect(mapStateToProps)(AllPost);

× TypeError: Object(...) is not a function

I am trying to build a simple counter using React and Redux but I am stuck with this error. The error comes up on line 23, that is const store=createStore(reducer). The React version I am using is 16.8.6.
import React, { Component } from 'react';
import {render} from 'react-dom';
import {createStore} from 'react';
import {connect,Provider} from 'react-redux';
import './styles.scss';
const InitialState = {
count: 0,
};
const IncrementValue = () => ({
type: 'INCREMENT',
});
const reducer = (state = InitialState, action) => {
if (action.type === 'INCREMENT') {
return {
count: state.count + 1,
};
}
return state;
};
const store = createStore(reducer);
class Counter extends Component {
render() {
const { count, increment } = this.props;
console.log({ count, increment });
return (
<main className="Counter">
<p className="count">0</p>
<section className="controls">
<button>Increment</button>
<button>Decrement</button>
<button>Reset</button>
</section>
</main>
);
}
}
const mapStatetoProps = state => {
return state;
};
const mapDispatchToProps = dispatch => {
return {
increment() {
dispatch(IncrementValue());
},
};
};
const CounterContainer=connect(mapStatetoProps, mapDispatchToProps)(Counter);
render(
<Provider store={store}>
<CounterContainer/>
</Provider>,
document.getElementById('root'),
);
createStore is a function of Redux, not React.
Change import to
import { createStore } from 'redux';

How to dispatch an action and show the data in the app.js using react/redux

I don't know how to load the data of the fetchLatestAnime action in the react app.js file.
My mission is to show the endpoint data that I am doing fetch.
I have already implemented the part of the reducers and action, which you can see in the part below. The only thing I need is to learn how to display the data.
App.js
import React from 'react';
import './App.css';
function App() {
return (
<div className="App">
</div>
);
}
export default App;
actions/types.js
export const FETCHING_ANIME_REQUEST = 'FETCHING_ANIME_REQUEST';
export const FETCHING_ANIME_SUCCESS = 'FETCHING_ANIME_SUCCESS';
export const FETCHING_ANIME_FAILURE = 'FETCHING_ANIME_FAILURE';
actions/animesActions.js
import{
FETCHING_ANIME_FAILURE,
FETCHING_ANIME_REQUEST,
FETCHING_ANIME_SUCCESS
} from './types';
import axios from 'axios';
export const fetchingAnimeRequest = () => ({
type: FETCHING_ANIME_REQUEST
});
export const fetchingAnimeSuccess = (json) => ({
type: FETCHING_ANIME_SUCCESS,
payload: json
});
export const fetchingAnimeFailure = (error) => ({
type: FETCHING_ANIME_FAILURE,
payload: error
});
export const fetchLatestAnime = () =>{
return async dispatch =>{
dispatch(fetchingAnimeRequest());
try{
let res = await axios.get('https://animeflv.chrismichael.now.sh/api/v1/latestAnimeAdded');
let json = await res.data;
dispatch(fetchingAnimeSuccess(json));
}catch(error){
dispatch(fetchingAnimeFailure(error));
}
};
};
reducers/latestAnimeReducers.js
import {
FETCHING_ANIME_FAILURE,
FETCHING_ANIME_REQUEST,
FETCHING_ANIME_SUCCESS
} from '../actions/types';
const initialState = {
isFetching: false,
errorMessage: '',
latestAnime: []
};
const latestAnimeReducer = (state = initialState , action) =>{
switch (action.type){
case FETCHING_ANIME_REQUEST:
return{
...state,
isFetching: true,
}
case FETCHING_ANIME_FAILURE:
return{
...state,
isFetching: false,
errorMessage: action.payload
}
case FETCHING_ANIME_SUCCESS:
return{
...state,
isFetching: false,
latestAnime: action.payload
}
default:
return state;
}
};
export default latestAnimeReducer;
reducers/index.js
import latestAnimeReducers from './latestAnimeReducers'
import {combineReducers} from 'redux';
const reducers = combineReducers({
latestAnimeReducers
});
export default reducers;
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
import resolvers from './redux/reducers/index';
import {createStore , applyMiddleware} from 'redux';
import {Provider} from 'react-redux';
import thunk from 'redux-thunk';
const REDUX_DEV_TOOLS = window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
const createStoreWithMiddleware = applyMiddleware(thunk)(createStore);
const store = createStoreWithMiddleware(resolvers , REDUX_DEV_TOOLS)
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
);
serviceWorker.unregister();
Ideally, this is how your app.js should look like. I created a working codesandbox for you here. Your initial latestAnime state was an empty array but the action payload you set to it is an object, so remember to pass payload.anime like i have done in the sandbox.
import React, { useEffect } from "react";
import { connect } from "react-redux";
import { fetchLatestAnime } from "./redux/actions/animesActions";
const App = props => {
const { fetchLatestAnime, isFetching, latestAnime, errorMessage } = props;
useEffect(() => {
fetchLatestAnime();
}, [fetchLatestAnime]);
console.log(props);
if (isFetching) {
return <p>Loading</p>;
}
if (!isFetching && latestAnime.length === 0) {
return <p>No animes to show</p>;
}
if (!isFetching && errorMessage.length > 0) {
return <p>{errorMessage}</p>;
}
return (
<div>
{latestAnime.map((anime, index) => {
return <p key={index}>{anime.title}</p>;
})}
</div>
);
};
const mapState = state => {
return {
isFetching: state.latestAnimeReducers.isFetching,
latestAnime: state.latestAnimeReducers.latestAnime,
errorMessage: state.latestAnimeReducers.errorMessage
};
};
const mapDispatch = dispatch => {
return {
fetchLatestAnime: () => dispatch(fetchLatestAnime())
};
};
export default connect(
mapState,
mapDispatch
)(App);

Trying to build a basic React-Redux click switcher but nothing is displayed

The app is just supposed to display 'Hello' and when you click on it, switch to 'Goodbye', but it won't render 'Hello'. I've set default state, connected everything, etc. but I can't figure out what I'm missing.
import React from 'react';
import { render } from 'react-dom';
import { Provider } from 'react-redux';
import { createStore } from 'redux';
import { connect } from 'react-redux';
import "./styles.css";
const switcheroo = () => {
return {
type: 'SWITCH'
};
};
const switchReducer = (state = {value: 'Hello'}, action) => {
switch (action.type) {
case 'SWITCH':
return { ...state, value: 'Goodbye' };
default:
return state;
}
}
class ClickMachine extends React.Component {
render() {
const { value, switcheroo } = this.props;
return(
<div >
<p onClick={switcheroo}>{value}</p>
</div>
)
}
};
const mapStateToProps = (state) => ({
value: state.value,
});
const mapDispatchToProps = (dispatch) => ({
switcheroo: () => dispatch(switcheroo()),
});
connect(mapStateToProps, mapDispatchToProps)(ClickMachine);
const store = createStore(switchReducer);
class AppWrapper extends React.Component {
render() {
return (
<Provider store={store}>
<ClickMachine />
</Provider>
);
};
};
const rootElement = document.getElementById("root");
render(<AppWrapper />, rootElement);
My CodeSandbox is here: https://codesandbox.io/s/k29r3928z7 and I have the following dependencies:
react
react-dom
react-redux
redux
Its because you've not assigned the connect function to a component, without which redux won't be associated with the ClickMachine Component
just change this line, it will work
ClickMachine = connect(mapStateToProps, mapDispatchToProps)(ClickMachine);
Sandbox link https://codesandbox.io/s/4x2pr03489

How to delete items in array redux store?

Im newbie at Redux and Redux, so im trying get a simple todo list.
I've got array in the store. Its okay with adding, but when im deleting item see this:
TypeError: Cannot read property 'map' of undefined
at
var items =this.props.tasks.map((item,i) => (this.props.deleteTask(item)} />));
in ListTODO.js
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import registerServiceWorker from './registerServiceWorker';
import { Provider } from 'react-redux';
import { createStore } from 'redux';
import reducer from './reducer';
const store = createStore(reducer);
ReactDOM.render(
<Provider store={store}>
<App className="container" />
</Provider>,
document.getElementById('root'));
registerServiceWorker();
App.js
import React, { Component } from 'react';
import InputTask from './InputTask';
import ListTODO from './ListTODO';
import { connect } from 'react-redux';
class App extends Component {
render() {
return (<div>
<strong>TODO LIST</strong>
<InputTask addTask={this.props.addTask} /><br />
<ListTODO tasks={this.props.store} deleteTask={this.props.deleteTask} />
</div>);
}
}
const mapStateToProps = state => {
return {
store: state
}
}
const mapDispatchToProps = dispatch => {
return {
addTask: (task) => {
dispatch({ type: 'UPDATE_LIST', payload: task })
},
deleteTask: (task) => {
dispatch({ type: 'DELETE_TASK', payload: task })
}
}
}
export default connect(
mapStateToProps,
mapDispatchToProps)
(App);
reducer.js
const initialState = ["task1", "task2"];
export default function todoList(state = initialState, action) {
switch (action.type) {
case 'UPDATE_LIST':
return [
...state,
action.payload
];
case 'DELETE_TASK':
console.log("DELETING", (action.payload))
return
state.filter(element => element !== action.payload);
default: return state;
}
}
ListTODO.js
import React, { Component } from 'react';
import TodoItem from './TodoItem';
import { connect } from 'react-redux';
class ListTODO extends Component {
constructor() {
super();
}
render() {
console.log("LIST TODO:"+ this.props.tasks);
var items =this.props.tasks.map((item,i) => (<TodoItem item={item} key={i} deleteTask={(item)=>this.props.deleteTask(item)} />));
return (
<ul>
{items}
</ul>
);
}
}
export default ListTODO;

Categories