React export constants - reactjs

I cant get why following approach doesn't work:
constants.js
import { createConstants } from '../utils';
export default createConstants(
'LOGIN_REQUEST',
'LOGIN_SUCCESS',
'LOGIN_FAILURE',
'LOGOUT',
'FETCH_DATA_REQUEST',
'RECEIVE_DATA'
);
utils.js
import React from 'react';
export function createConstants(...constants) {
return constants.reduce((acc, constant) => {
acc[constant] = constant;
return acc;
}, {});
}
Next i want to import LOGIN_REQUEST for example as redux action.
import { LOGIN_REQUEST, LOGIN_SUCCESS, LOGIN_FAILURE, LOGOUT } from '../constants';
But i'm getting undefined each time for all imported constants.
It works only when i'm defining like this:
export const LOGIN_REQUEST = 'LOGIN_REQUEST';
Maybe somebody has some ideas?

Your first approach is called a default export. It doesn't work because the syntax you're using is not correct.
From the MDN export entry, that's how you write a default export:
// module "my-module.js"
export default function cube(x) {
return x * x * x;
}
Your second approach is called named export and it works because it has the right syntax. Again from MDN:
export const foo = Math.sqrt(2); // exports a constant
Hope it helps.

Export doesnt work like that. You can try something like:
import allConstants from '../constants';
Then use a constant like:
allConstants.LOGIN_REQUEST

Related

React redux - actions

Recently I'm trying my best in redux, and I have seen a really good folder structure project, I tried to get the same structure, but the same way didn't work...
E.g. I've got a path something like that: ./src/_actions and inside this folder I've got "user.actions.js", "alert.actions.js", "index.js".
In alert.actions.js I've got something like that:
import { alertConstants } from "../_constants/alert.constants";
export const alertActions = {
success,
error,
clear,
};
function success(message) {
return { type: alertConstants.SUCCESS, message };
}
function error(message) {
return { type: alertConstants.ERROR, message };
}
function clear() {
return { type: alertConstants.CLEAR };
}
And I'd love to import all of them from one place like to the folder where path is "./../test.js":
import {alertActions} from "./../_actions";
import {useDispatch} from "react-redux";
export const test = () => {
const dispatch = useDispatch();
return (
<button onClick={() => dispatch(alertActions.success("test"))}> Click </button>
)
}
but I got something like "alertActions.success" is undefined. I don't know what I'm doing wrong.. In that project, index.js has been empty as well... that object supposed to export those all functions.. somebody know any solution? :(
You need to export the object after the functions are made. Usually they are hoisted, but in this case you are probably using strict mode and they are not. You have to either move the export object or better yet export all of them individually and then when you are importing them you should write:
import * as alertActions from 'youfile'
And if you want to export a whole object you should export it like:
export default alertActions
And then you need to import them like:
import alertActions from 'yourfile'
and access them:
alrtActions.error()

Is there a way to require in multiple modules into a file, which is then exported again as a single module?

Currently working with Redux and was wondering if there was a way to require in multiple modules into a single file, which is then exported again as a single module?
For example, in my actions/bookmark.js I group all actions related to bookmarks accordingly:
module.exports = {
fetchBookmarkList: () => {
return {
type: 'FETCH_LIST'
}
},
fetchBookmark: () => {
return {
type: 'FETCH_BOOKMARK'
}
}
}
Then in my actions/index.js file, I require in all groups of actions (which will include bookmark actions as well as others). Then I would like to export the entire file as a single module.
Schematically I had something like this in mind (obviously this code does not work):
actions/index.js:
module.exports = {
require('./bookmark');
require('./tags');
}
The reason that I want to do this is so that I only have to import a single action file that contains all my actions (i.e. the actions/index.js file):
Example component:
import React, { Component } from 'react';
import { connect } from 'react-redux';
import * as actions from '../actions';
class BookmarkList extends Component {
constructor(props) {
super(props);
this.props.fetchBookmarkList();
}
render() {
return (
<div></div>
);
}
}
export default connect(null, actions)(BookmarkList);
I see that you es6 modules syntax in components then, why not in your redux files?
export const fetchBookmarkList = () => {
return {
type: 'FETCH_LIST'
}
};
export const fetchBookmark = () => {
return {
type: 'FETCH_BOOKMARK'
}
}
Based on this reference I think it could be possible to re-export everything like this:
export * from './bookmark'
export * from './tags;
But haven't tried it and I could be wrong.
I would NOT recommend you to pass all the actions to mapDispatchToProps, only the actions needed by your component
But you could just use in actions/index.js:
Using the spread operator:
module.exports = {
...require('./bookmark');
...require('./tags');
}
And in ES6 syntax:
actions/index.js:
export * from './bookmark'
export * from './tags'

react imports not working as expected

I'm trying to import a style variable from another file but it tells me that it's undefined
My directory:
Components
Login
LoginForm.js
appstyle.js
appstyle.js
export default AppStyles = {
colour: {
custom: 'rgb(86,200,95)'
}
}
Login.js
import React, { Component } from 'react';
import AppStyles from '../appstyle';
class LoginForm extends Component {
render() {
const header = {
color: AppStyles.color.custom
}
return (<div ><p style={header}> test </p></div>)
}
error:
./src/components/appstyle.js
Line 1: 'AppStyles' is not defined no-undef
Search for the keywords to learn more about each error.
What is wrong? I honestly cant see what i did that's making it not recognize it.
Your export statement is wrong, if you want to name something you need to declare a variable:
Or you can also NOT name it, as it is a default export, and name the import only in your Login file.
export default {
[...]
}
export default AppStyles = {
colour: {
custom: 'rgb(86,200,95)'
}
}
AppStlyes Is not defined. You have no variable declaration.
Instead it should look like this.
const AppStyles = {
colour: {
custom: 'rgb(86,200,95)'
}
};
export default AppStyles;
Rewrite appstyle.js:
const AppStyles = ...;
export default AppStyles;
Spelling error:
AppStyles sets a property colour:
export default {
colour: {
custom: 'rgb(86,200,95)'
}
}
And you are looking for a property named color:
AppStyles.color.custom
EDIT:
You also need to directly export the object. The way you are attempting to export is causing the undefined issue.

Actions may not have an undefined "type" property

I am using react native and redux, this is my action:
import EMPLOYEE_UPDATE from './types';
export const employeeUpdate = ({ prop, value }) => {
return (
{
type: EMPLOYEE_UPDATE,
paylaod: { prop, value }
}
);
};
but i get this error:
Actions may not have an undefined "type" property. Have you misspelled a constant?
EDIT:
the types.js file is:
export const LOGIN_USER_FAILED = 'loing_user_failed';
export const SHOW_SPINNER = 'show_spinner';
export const EMPLOYEE_UPDATE = 'employee_update';
You need to import EMPLOYEE_UPDATE from types file like this
import { EMPLOYEE_UPDATE } from './types';
You need to import the const as a named import rather than a default import since you have exported it as a named const.
import {EMPLOYEE_UPDATE} from './types';
See this answer for details on named and default exports:
in reactjs, when should I add brackets when import

ES6 how to do multiple default exports

I am still getting a hang of react+redux, and ES6. I am trying to implement socketio, and I come across the problem of having to export socketio connect with my redux's connect.
redux connect
export default connect(mapStateToProps, matchDispatchToProps)(UserList);
socketio connect
export default socketConnect(App);
Question
What is the correct syntax to make them work together?
You can't have more than one default export.
Instead, use named exports.
// moduleName.js
export const ConnectedUserList = connect(mapStateToProps, matchDispatchToProps)(UserList)
export const RealTimeApp = socketConnect(App);
Require the exports by name.
// otherModule.js
import { ConnectedUserList, RealTimeApp } from "./moduleName"
You can mix default export and named export.
export default ConnectedUserList = connect(mapStateToProps, matchDispatchToProps)(UserList)
export const RealTimeApp = socketConnect(App);
And after, you can import your exports :
import ConnectedUserList, { RealTimeApp } from "./moduleName"
One possibility I've not seen mentioned. You can have only one default export, but what you export can be an object with multiple members:
// MyModule.js
const componentA => () => {return <div>Component A</div>;}
const componentB => () => {return <div>Component B</div>;}
export default { componentA, componentB };
And then:
import MyModule from "./MyModule";
MyModule.componentA();
export default () => {
return {export1, export2};
}
export default { constOne, constTwo } and import data from './data.js' will do the trick. To access the data in the target file, it would be like so: {data.constOne} or {data.constTwo}
Example
Lets say we have the following data.js file:
const summary = [
{ label: 'Turned pro', content: '2020' },
{ label: 'Profession', content: 'Engineer' }
]
const reputation = [
{ community: 'Code Review', points: 176 },
{ community: 'Game Development', points: 101 }
]
export default { summary, reputation }
One way to import and use the data, would be like so:
import data from './data.js'
function App(){
return (
<div>
{data.summary.map((el) => <p>{el.label}</p> )}
</div>
)
}

Resources