React Native Firebase Fetching Only One Data - javascript

How can I fetch only one data and write it to Header ?
I am using firebase and react-redux.
firebase structure i try to write "organization": inovanka:
Action File Codes:
import firebase from 'firebase';
import { Actions } from 'react-native-router-flux';
import { ORGANIZATION_NAME_DATA_SUCCESS } from './types';
export const organizationName = () => {
const { currentUser } = firebase.auth();
return (dispatch) => {
firebase.database().ref(`/organizations/${currentUser.uid}`)
.on('value', snapshot => {
dispatch({ type: ORGANIZATION_NAME_DATA_SUCCESS, payload: snapshot.val() });
});
};
}
Reducer File :
import { ORGANIZATION_NAME_DATA_SUCCESS } from '../actions/types';
const INITIAL_STATE = {
};
export default (state = INITIAL_STATE, action) => {
switch (action.type) {
case ORGANIZATION_NAME_DATA_SUCCESS:
console.log(action); // data retrieved as array
return action.payload
default:
return state;
}
};
Component: (I would like to write it to this)
class HomePage extends Component {
componentWillMount() {
}
render() {
return (
<Container>
<Header>
<Text> i would like to write it here </Text>
</Header>
<Content>
</Content>
</Container>
);
}
}
const mapStateToProps = ({ homepageResponse }) => {
const organizationArray = _.map(homepageResponse, (val, uid) => {
return { ...val, uid }; //
});
return { organizationArray };
};
export default connect(mapStateToProps, { organizationName })(HomePage);

Change this:
firebase.database().ref(`/organizations/${currentUser.uid}`)
.on('value', snapshot => {
to this:
firebase.database().ref(`/organizations/${currentUser.uid}`)
.once('value', snapshot => {
using once() will read data only one time, thus fetching only one data

Solution is Here !
Action File:
export const organizationName = () => {
const { currentUser } = firebase.auth();
return (dispatch) => {
firebase.database().ref(`/organizations/${currentUser.uid}`)
.once('value', snapshot => {
_.mapValues(snapshot.val(), o => {
console.log(o);
dispatch({ type: ORGANIZATION_NAME_DATA_SUCCESS, payload: {organization: o.organization, fullname: o.fullname }});
});
});
};
}
Reducer File
const INITIAL_STATE = {
organization: '',
};
export default (state = INITIAL_STATE, action) => {
switch (action.type) {
case ORGANIZATION_NAME_DATA_SUCCESS:
console.log(action);
return {...state, organization:action.payload.organization };
default:
return state;
}
};
Component File MapToStateProps and componentWillMount
const mapStateToProps = state => {
const { organization, fullname } = state.homepageResponse;
console.log("burada" + organization);
return { organization, fullname };
};
componentWillMount(){
this.props.organizationName();
}
*Last Step Header *
render() {
return (
<Container>
<Header>
<Text> { this.props.organization } </Text>
</Header>
</Container>
}
Thank You Everyone

Related

Async api fetch with redux thunk

I'm having trouble fetching a list of users from an api. I think issue might be in my mapDispatchToProps function but I'm not sure. Everything else seems fine to me. I'm new to redux and I'm kinda having a hard time wrapping my head around it so any help is appreciated
The list with the users would ideally be displayed as soon as the component mounts. I did the same thing without redux store and it was working just fine, I'm just not really sure how to integrate redux
Actions
export const startLoading = () => {
return {
type: START_LOADING
}
}
export const updateUserData = payload => {
return {
type: UPDATE_USER_DATA,
payload
}
}
export const updateUserError = payload => {
return {
type: UPDATE_USER_ERROR,
payload: payload
}
}
export function fetchUsers() {
return dispatch => {
dispatch(startLoading());
fetch('https://jsonplaceholder.typicode.com/users')
.then(res => res.json())
.then(data => {
data = data.filter(user => user.id < 4);
data.forEach(user => {
user.isGoldClient = false;
user.salary = '4000';
user.photo = userThumbnail;
})
.then(data => {
dispatch(updateUserData(data));
}).catch(error => {
dispatch(updateUserError(error));
})
});
};
};
Reducers
const initialState = {
loading: false,
users: [],
error: null
};
export function userReducer(state=initialState, action){
switch(action.type){
case START_LOADING:
return {
...state,
loading: true
}
case UPDATE_USER_DATA:
return {
...state,
loading: false,
users: action.payload,
error: null
}
case UPDATE_USER_ERROR:
return {
...state,
error: action.payload,
loading: false,
users: []
};
default:
return state;
};
};
Component
class Home extends React.Component {
constructor(props) {
super(props);
this.state = {
users: [],
usersAreDisplayed: true
};
}
componentDidMount() {
fetchUsers();
}
render(){
return (
<UserList users={this.state.users} />
)
}
}
function mapStateToProps(state){
return { users: state.users }
}
function mapDispatchToProps(dispatch){
return {
fetchUsers: payload => dispatch(updateUserData(payload)),
}
}
export default connect(mapStateToProps, mapDispatchToProps)(Home);
Looks like you are not calling the actual fetchUsers at all.
Change the component code like this
function mapStateToProps(state){
return { users: state.users }
}
// remove this function
// function mapDispatchToProps(dispatch){
// return {
// fetchUsers: payload => dispatch(updateUserData(payload)),
// }
// }
export default connect(mapStateToProps, {fetchUsers})(Home); //<---- destructure it here. Also import the function (action)
1a. fetchUsers function needs to be accessed using this.props
componentDidMount() {
this.props.fetchUsers();
}
There is an extra then block after forEach.
Remove it.
export function fetchUsers() {
return (dispatch) => {
dispatch(startLoading());
fetch("https://jsonplaceholder.typicode.com/users")
.then((res) => res.json())
.then((data) => {
data = data.filter((user) => user.id < 4);
data.forEach((user) => {
user.isGoldClient = false;
user.salary = "4000";
user.photo = userThumbnail;
});
dispatch(updateUserData(data)); // <------ no extra .then is required
})
.catch((error) => {
dispatch(updateUserError(error));
});
};
}
Also <UserList users={this.state.users} /> needs to be <UserList users={this.props.users} /> As already mentioned by #Nsevens
You are mapping redux state into your component's props.
So you should load the users from the component's props and not it's state:
render(){
return (
<UserList users={this.props.users} />
)
}

React app 'Slowing down' when i try to dispatch action inside firebase.auth().onAuthStateChanged() method

I am trying to implement Firebase Authentication in my React App.
I have buttons LogIn and LogOut, which are working correctly(i can console.log uid)
Redirecting is fine as well.
Then i tried to add new reducer 'user' : {uid: uid} or 'user': {} if logged out.
At this point my App doesn't want to run and browser shows the notification "A web page is slowing your browser".
Thats GitHub link
App.js:
import ReactDOM from "react-dom";
import Navigation from "../routers/Navigation";
import { firebase, database } from "../firebase/firebase";
import { startSetExpenses, setFiltersText } from "../redux/actions";
import { createBrowserHistory } from "history";
import { connect } from "react-redux";
import {logIn, logOut} from '../redux/actions'
let history = createBrowserHistory();
export function App(props) {
firebase.auth().onAuthStateChanged((user) => {
if (!user) {
props.dispatch(logOut())
history.push("/");
} else {
props.dispatch(logIn(user.uid))
if (history.location.pathname === "/") {
history.push("/dashboard");
}
}
});
return (
<div>
<h1>Expenses App</h1>
<Navigation history={history}/>
</div>
);
}
let mapStoreToProps = (dispatch) => {
return {
dispatch
}
}
export default connect(mapStoreToProps)(App)
RootReducer.js :
const initialState = {
filters: {
text: ""
},
expenses: [],
user: {}
};
function userReducer(state = {}, action) {
const {type, uid} = action
switch (type) {
case "LOGIN":
return {
uid: uid
}
case "LOGOUT":
return {}
default :
return state;
}
}
function expensesReducer(state = initialState.expenses, action) {
const { type,id, description, value, updates,expenses } = action;
switch (type) {
case "ADD_EXPENSE":
return [
...state,
{
id,
description,
value,
},
];
case "REMOVE_EXPENSE":
if (state.findIndex(expense => expense.id === id) < 0) throw new Error('index is not found')
return state.filter((expense) => expense.id !== id);
case "UPDATE_EXPENSE":
return state.map((expense) => {
return expense.id === id ? { ...expense, ...updates } : expense;
});
case "SET_EXPENSES":
if (expenses) {
return expenses
}
default:
return state;
}
}
function filtersReducer(state = initialState.filters, action) {
const {type, text} = action;
switch (type) {
case 'SET_FILTERS_TEXT':
return {...state, text}
default:
return state;
}
}
const rootReducer = combineReducers({
filters: filtersReducer,
expenses: expensesReducer,
user: userReducer
})
export default rootReducer
Actions.js:
import {database, firebase, googleProvider} from "../firebase/firebase";
export function logIn(uid) {
return (dispatch) => {
console.log('uid inside actionCreator', uid)
dispatch({
type: "LOGIN",
uid: uid
})
}
}
export function logOut() {
return (dispatch) => {
console.log('logged out')
dispatch({type: 'LOGOUT'})
}
}
export function startLogIn() {
return () => {
return firebase.auth().signInWithPopup(googleProvider)
}
}
export function startLogOut() {
return () => {
return firebase.auth().signOut()
}
}
export function addExpense({ id, description, value } = {}) {
return {
type: "ADD_EXPENSE",
id,
description,
value,
};
}
export const startAddExpense = (expense) => {
return (dispatch) => {
let newId = database.ref("expenses").push().key;
const { description, value } = expense;
return database
.ref("expenses/" + newId)
.set({ description, value })
.then(() => {
dispatch(
addExpense({
type: "ADD_EXPENSE",
id: newId,
description,
value,
})
);
});
};
};
export function removeExpense(id) {
return {
type: "REMOVE_EXPENSE",
id,
};
}
export const startRemoveExpense = (id) => {
return (dispatch) => {
return database
.ref("expenses/" + id)
.remove()
.then(() => {
console.log("removing expense with id : " + id);
dispatch(removeExpense(id));
})
.catch((error) => {
console.log(`Expense with id:${id} was not removed`);
console.log(error)
});
};
};
export function updateExpense(id, updates) {
return {
type: "UPDATE_EXPENSE",
id,
updates,
};
}
export const startUpdateExpense = (id, updates) => {
return (dispatch) => {
return database.ref('expenses/' + id)
.update(updates)
.then(() => {
dispatch(updateExpense(id, updates))
})
.catch((err) => {
console.log('Error with updating an expense from firebase')
console.log(err)
})
}
}
export function setFiltersText(text) {
return {
type: "SET_FILTERS_TEXT",
text,
};
}
export const setExpenses = (expenses) => {
return {
type: "SET_EXPENSES",
expenses: [...expenses],
};
};
export const startSetExpenses = () => {
return (dispatch) => {
//get expenses from database
//.then dispatch expenses to state with setExpenses
return database
.ref("expenses")
.once("value")
.then((snapshot) => {
const expensesObj = snapshot.val();
let expenses = [];
for (let property in expensesObj) {
expenses = [
...expenses,
{
id: property,
description: expensesObj[property].description,
value: expensesObj[property].value,
},
];
}
dispatch(setExpenses(expenses));
});
};
};

React-Redux, how to change state?

i have such problem: I'm making To-Do-List, and now I want to make EditMode for my tasks. But when I try to do it, it returns string not an array, and that's why I have 3 errors (map,some,filter = is not a function). So I don't know how to change state(task) and return changed array.
Some details: I'm using connect to get props.
Component's code
class Item extends React.Component {
state = {
statusChange: false,
task: ''
}
activeStatusChange = () => {
this.setState( {
statusChange: true
}
);
}
deActivateStatusChange = () => {
this.setState( {
statusChange: false
}
);
this.props.editTask(this.state.task)
}
onStatusChange = (e) => {
this.setState({
task: e.currentTarget.value
})
}
render(){
return (
<div className={s.item}>
<span onClick={this.props.editStatus} className={s.statusTask}>
{this.props.status ? <img src="https://img.icons8.com/doodle/48/000000/checkmark.png"/>
: <img src="https://img.icons8.com/emoji/48/000000/red-circle-emoji.png"/>}
</span>
{ this.state.statusChange
? <input onChange={this.onStatusChange} autoFocus={true} onBlur={this.deActivateStatusChange} value={this.state.task} />
: <span className={this.props.status === true ? s.task : s.taskFalse} onClick={this.activeStatusChange}> {this.props.task} </span>}
<span onClick={this.props.deleteTask} className={s.close}><img src="https://img.icons8.com/color/48/000000/close-window.png"/></span>
</div>
)
}
}
export default Item;
Reducer's code
import React from 'react'
import shortid from 'shortid';
const ADD_TASK = 'ADD_TASK'
const EDIT_STATUS = 'EDIT_STATUS'
const TASK_DELETE = 'TASK_DELETE'
const REMOVE_ALL_DONE = 'REMOVE_ALL_DONE'
const REMOVE_ALL_TASKS = 'REMOVE_ALL_TASKS'
const EDIT_TASK = 'EDIT_TASK'
const initialState = {
tasks: []
};
const mainReducer = (state = initialState, action) => {
switch (action.type) {
case ADD_TASK: {
return {
...state,
tasks: [{
id: shortid.generate(),
task: action.task,
status: false
}, ...state.tasks]
}
}
case EDIT_STATUS: {
return {
...state,
tasks: state.tasks.map(task => task.id === action.id ? {...task, status: !task.status} : task)
}
}
case TASK_DELETE: {
return {
...state,
tasks: state.tasks.filter(t => t.id !== action.id)
}
}
case REMOVE_ALL_DONE: {
return {
...state,
tasks: state.tasks.filter(t => !t.status)
}
}
case REMOVE_ALL_TASKS: {
return {
...state,
tasks: []
}
}
case EDIT_TASK: {
return {
...state,
tasks: action.task
}
}
default:
return state
}
}
export const addTask = task => ({type: 'ADD_TASK', task});
export const editStatus = id => ({type: 'EDIT_STATUS', id})
export const deleteTask = id => ({type: 'TASK_DELETE', id})
export const removeAllDone = () => ({type:'REMOVE_ALL_DONE'})
export const removeAllTasks = () => ({type: 'REMOVE_ALL_TASKS'})
export const editTask = task => ({type: 'EDIT_TASK', task})
export default mainReducer;
You should create a container that uses the methods mapDispatchToProps so you can use your actions in the component.
https://react-redux.js.org/using-react-redux/connect-mapdispatch
So lets do it. Just create a file that will be your container for that component and put the code like this:
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import Item from 'wherever your component is';
import { addTask } from 'wherever your action is';
const mapStateToProps = ({ }) => ({
// Here you can pass the redu state to your component
});
const mapDispatchToProps = (dispatch) => ({
...bindActionCreators({
// Here you pass the action to your component
addTask
}, dispatch)
});
export default connect(
mapStateToProps,
mapDispatchToProps,
)(Item);
Then when you want to use the Item component import it from the container and it will receive in props both the action and the state that you are passing from the container file.
In you Item component you can use the action like this:
// ITem component
render() {
return (
<button onClick={this.props.addTask} />
)
}
If any doubt just let me know!

Change in redux state does not cause change in component / componentDidUpdate not called

I have a post details component where on clicking the like button the redux state changes the redux state is like
posts
->postDetails
I'am changing the liked property and number of likes of postDetais object, On clicking the like button the liked property is set to true from false and vice versa and the number of likes is incremented.
However the state is changing but the componentDidUpdate method is not firing
PostDetails.js
import React, { Component } from "react";
import { connect } from "react-redux";
import {
getPostData,
likePost,
unlikePost
} from "../../store/actions/postsActions";
import { Icon, Tooltip } from "antd";
import { Link } from "react-router-dom";
export class PostDetails extends Component {
state = {
postData: this.props.postDetails
};
componentDidMount() {
this.props.getPostData(this.props.match.params.post_id);
}
componentDidUpdate(prevProps, prevState, snapshot) {
console.log(this.props.postDetails);
if (prevProps.postDetails !== this.props.postDetails) {
this.setState({
postData: this.props.postDetails
});
}
}
render() {
const { postData } = this.state;
const liked = postData.liked;
return (
<div className="postDetails">
{postData && (
<div className="postDetailsContainer">
<div className="postImage">
<img src={postData.imageUrl} alt={postData.caption} />
</div>
<div className="postContent">
<div className="postContent__header">
<Link
to={`/user/${postData.username}`}
className="postContent__headerContent"
>
<img
src={postData.profileUrl}
alt={postData.username}
className="postContent__profileImage"
/>
<p className="postContent__username">{postData.username}</p>
</Link>
</div>
<div className="postComments" />
<div className="postInfo">
<div className="postActions">
{liked ? (
<Tooltip title="Unlike post">
<Icon
type="heart"
className="likePost"
theme="filled"
style={{ color: "#d41c00" }}
onClick={() => this.props.unlikePost(postData.id)}
/>
</Tooltip>
) : (
<Tooltip title="Like post">
<Icon
type="heart"
className="likePost"
onClick={() => this.props.likePost(postData.id)}
/>
</Tooltip>
)}
<Tooltip title="Comment">
<Icon type="message" className="commentButton" />
</Tooltip>
</div>
<Tooltip title="Refresh comments">
<Icon type="reload" className="reloadComments" />
</Tooltip>
</div>
<div />
</div>
</div>
)}
</div>
);
}
}
const mapStateToProps = state => {
return {
postDetails: state.posts.postDetails
};
};
const mapDispatchToProps = dispatch => {
return {
getPostData: postId => dispatch(getPostData(postId)),
likePost: postId => dispatch(likePost(postId)),
unlikePost: postId => dispatch(unlikePost(postId))
};
};
export default connect(
mapStateToProps,
mapDispatchToProps
)(PostDetails);
postsReducer.js
const initialState = {
creatingPost: false,
feed: [],
createdPost: false,
feedUpdated: false,
postDetails: {}
};
const postsReducer = (state = initialState, action) => {
switch (action.type) {
case "CREATING_POST":
return {
...state,
creatingPost: true,
createdPost: false
};
case "ADD_POST":
return {
...state,
feed: state.feed.concat(action.payload)
};
case "FETCH_FEED":
return {
...state,
feed: action.payload
};
case "CREATED_POST":
return {
...state,
creatingPost: false,
createdPost: true
};
case "UPDATE_FEED":
return {
...state,
feed: action.payload,
feedUpdated: true
};
case "GET_POST_DATA":
return {
...state,
postDetails: action.payload
};
case "RESET_FEED_UPDATED":
return {
...state,
feedUpdated: false
};
case "RESET_CREATED_POST":
return {
...state,
createdPost: false
};
case "LIKED_POST":
const { postDetails } = state;
postDetails.liked = true;
postDetails.likes += 1;
return {
...state,
postDetails: postDetails
};
case "UNLIKED_POST":
const postDetails1 = state.postDetails;
postDetails1.liked = false;
postDetails1.likes -= 1;
return {
...state,
postDetails: postDetails1
};
case "CLEAR_POST_DATA":
return initialState;
default:
return state;
}
};
export default postsReducer;
postsActions.js
import Axios from "axios";
import moment from "moment";
import store from "../store";
export const createPost = postData => {
return (dispatch, getState) => {
dispatch({ type: "CREATING_POST" });
Axios.post("/api/post/new", {
imageUrl: postData.imageUrl,
caption: postData.caption
})
.then(res => {
dispatch({ type: "CREATED_POST" });
dispatch({ type: "ADD_POST", payload: res.data.post });
})
.catch(err => {
console.log(err);
});
};
};
export const fetchFeed = () => {
return (dispatch, getState) => {
Axios.get("/api/user/feed")
.then(res => {
var feed = res.data.feed;
const state = store.getState();
const likedPosts = state.user.userData.likedPosts;
for (var i = 0; i < feed.length; i++) {
for (var j = 0; j < feed.length - i - 1; j++) {
if (moment(feed[j + 1].createdAt).isAfter(feed[j].createdAt)) {
var temp = feed[j];
feed[j] = feed[j + 1];
feed[j + 1] = temp;
}
}
}
for (var i = 0; i < feed.length; i++) {
if (likedPosts.indexOf(feed[i]._id) > -1) {
feed[i]["liked"] = true;
} else {
feed[i]["liked"] = false;
}
}
console.log(feed);
dispatch({ type: "FETCH_FEED", payload: feed });
})
.catch(err => {
console.log(err);
});
};
};
export const likePost = postId => {
return (dispatch, getState) => {
Axios.put("/api/post/like", { postId: postId })
.then(res => {
const feed = store.getState().posts.feed;
feed.forEach(post => {
if (post._id === postId) {
post.liked = true;
}
});
dispatch({ type: "UPDATE_FEED", payload: feed });
dispatch({ type: "LIKED_POST", payload: res.data.postId });
})
.catch(err => {
console.log(err);
});
};
};
export const unlikePost = postId => {
return (dispatch, getState) => {
Axios.put("/api/post/unlike", { postId: postId })
.then(res => {
const feed = store.getState().posts.feed;
feed.forEach(post => {
if (post._id === postId) {
post.liked = false;
}
});
dispatch({ type: "UPDATE_FEED", payload: feed });
dispatch({ type: "UNLIKED_POST", payload: res.data.postId });
})
.catch(err => {
console.log(err);
});
};
};
export const getPostData = postId => {
return (dispatch, getState) => {
Axios.get(`/api/post/${postId}`)
.then(res => {
const likedPosts = store.getState().user.userData.likedPosts;
if (likedPosts.indexOf(postId) > -1) {
res.data.post["liked"] = true;
} else {
res.data.post["liked"] = false;
}
dispatch({ type: "GET_POST_DATA", payload: res.data.post });
})
.catch(err => {
console.log(err);
});
};
};
export const resetFeedUpdated = () => {
return (dispatch, getState) => {
dispatch({ type: "RESET_FEED_UPDATED" });
};
};
export const resetCreatedPost = () => {
return (dispatch, getState) => {
dispatch({ type: "RESET_CREATED_POST" });
};
};
Your LIKED_POST and UNLIKED_POST reducer cases are not pure - they are are mutating the existing postDetails object in the state and putting it back into state so connect is optimizing and not re-rendering when it does a shallow equals comparison on postDetails from the previous and next props in componentShouldUpdate. Make sure you're creating a completely new value for postDetails like:
case "LIKED_POST":
const { postDetails } = state;
const newPostDetails = {
...postDetails,
liked: true,
likes: postDetails.likes + 1,
};
return {
...state,
postDetails: newPostDetails
};
You should check, if the comparison if (prevProps.postDetails !== this.props.postDetails) ever hits. Because with the like function you only change properties of the same object, the comparison will fail, because it's still the same object reference for postDetails. Try to return a new object in your reducer:
case "LIKED_POST":
const { postDetails } = state;
postDetails.liked = true;
postDetails.likes += 1;
return {
...state,
postDetails: {
...postDetails
},
}
Also if you're not changing anything of the object inside the component but in Redux store why not use the component property directly? You can remove the state object and the componentDidUpdate. Also you could refactor it to a function component.
render() {
const { postDetails: postData } = this.props;
...
}
When working with Redux, never forget the three principles
Single Source of truth
State is ready only
Reducers must be pure functions: Reducers take previous state and some action and modifies it and returns new state. We should never mutate state. We should create new objects and return them.
You have mutated existing state in your reducer functions. This doesnt trigger componentdidupdate because, connect method ( it checks mapStateToProps) treats that there is nothing that changed (It checks reference and since reference didnt change Component is not invoked).
You can use Object.assign or use spread operator which helps to make your reducers return a new object.
Change your Liked and unlinked posts reducer functions to return a new object instead of mutating existing object.
#azundo added how your code should be to achieve what you need.

Redux doesn't update state

I have a problem with Redux doesn't update the state. Component gets right initial state. Action is dispatched right, data is fetched right and is accesible in action payload inside reducer. Reducer is executing, right case in switch is picked. Just new state doesn't appear in component. I have three others components where it works just fine, only this one cracks.
component
import fetchLinksPage from '../state/links/actions'
...
let Links = ({linksPageLoaded, linksPage, fetchLinksPage}) => {
useEffect( () => {
if(!linksPageLoaded) {
fetchLinksPage()
console.log(linksPage)
}
},[])
return ( ... )
}
const mapStateToProps = ({linksPageReducer}) => {
return linksPageReducer
}
const mapDispatchToProps = dispatch => {
return {
fetchLinksPage: () => dispatch(fetchLinksPage())
}
}
Links = connect(mapStateToProps, mapDispatchToProps)(Links)
actions
// action types
export const GET_LINKS_PAGE = 'GETLINKSPAGE'
export const LINKS_PAGE_LOADED = 'LINKSPAGELOADED'
export const LINKS_PAGE_ERROR = 'LINKSPAGEERROR'
// action creators
export const getLinksPage = () => {
return {
type: GET_LINKS_PAGE
}
}
export const linksPageLoaded = (data) => {
return {
type: LINKS_PAGE_LOADED,
payload: data
}
}
export const linksPageError = (error) => {
return {
type: LINKS_PAGE_ERROR,
payload: error
}
}
const fetchLinksPage = () => {
return dispatch => {
dispatch(getLinksPage())
fetch('http://portfolio.adamzajac.info/_/items/links?fields=*,logo.*.*')
.then(response => response.json())
.then(data => {
dispatch(linksPageLoaded(data.data))
})
.catch( error => {
dispatch(linksPageError(error))
})
}
}
export default fetchLinksPage
reducer
import * as actions from './actions.js'
const linksPageReducer = (state={}, action) => {
switch (action.type) {
case actions.GET_LINKS_PAGE:
return { ...state, linksPageLoading: true }
case actions.LINKS_PAGE_LOADED:
//console.log('update state')
return { ...state, linksPage: action.payload, linksPageLoading: false, linksPageLoaded: true }
case actions.LINKS_PAGE_ERROR:
return { ...state, linksPageError: action.payload, linksPageLoading: false}
default:
return { ...state, linksPageLoading: false, linksPageLoaded: false, linksPage:[], linksPageError:''}
}
}
export default linksPageReducer
store
import aboutPageReducer from './state/about/reducer'
import projectsPageReducer from './state/projects/reducer'
import skillsPageReducer from './state/skills/reducer'
import linksPageReducer from './state/links/reducer'
const rootReducer = combineReducers({
aboutPageReducer,
projectsPageReducer,
skillsPageReducer,
linksPageReducer
})
const store = createStore(
rootReducer,
applyMiddleware(thunk)
)

Categories