how to Pass props from react-redux to container component? - reactjs

here is my code in redux ,everythig is fine the code are working
export const loginUser = (values, history, setFieldError, setSubmitting) => {
i take **email**, split it until # and take it as a username ,
const username = values.email.split("#")[0]
return () => {
//then i pass it to axios params as a query name
axios.get(url, {
params: {
name: username
}
}).then((response) => {
//if res ok
console.log("username", username)
history.push("/user")
}).catch(error => console.error(error))
setSubmitting(false);
}
}
now i should pass that usernam as a props to my Dashboard witch is a component
const Dashboard = ({logoutUser,user}) => {
const history = useHistory();
return (
<StyledFromArea bg={colors.dark2}>
here i need to show a *username*
should be like **Hello , YourName**
<StyledTitle size={65}>Hello, {user.user}
//but its undefided
{console.log("user",user.name)}
</StyledTitle>
*same here*
<ExtraText color={colors.light1}>{user.email}</ExtraText>
{console.log("email",user.email)}
<Userinfo/>
<ButtonGroup>
<StyledButton to="#" onClick={()=> logoutUser(history)}> Logout
</StyledButton>
</ButtonGroup>
</StyledFromArea>
)
}
//i use **mapStateToProps**but maybe it's not working ,i think the //problem comes from here
const mapStateToProps =({session})=>({
user:session.user
})
export default connect(mapStateToProps,{logoutUser})(Dashboard) ;
my code
https://codesandbox.io/s/login-page-forked-6gcvq?file=/src/pages/Dashboard.js

First you must use connect with class componets but you use functional style. Seсond in session absent your user data, you must create another reducer for user. Demo

Related

Issue with updating state in react-redux

There is a React component which contains list of users and form to invite a new user.
"inviteNewUser" is a *POST* request in backend
"getUsers" is a *GET* request to get all users
The problem is that after clicking on button "Invite User" I would like to see the invited user in the list of users ("currentUsers" in code below) without refreshing the page. But right now it happens only after I refresh the whole page.
when I'm trying to make a GET request to get all users right after inviteNewUser(data) (POST request) I'm getting the "old" user list without user which I just invited. So the "currentUsers" list is not immediately updated
Could someone help me to fix this issue ?
export function MyForm({
getUsers,
inviteNewUser,
userId,
currentUsers
}) {
useEffect(() => {
getUsers(userId);
}, [userId]);
function handleSendInvite(data) {
inviteNewUser(data);
getUsers(data.userId);
}
return (
<>
{currentUsers.map((user) => (
<UserItem
key={user.userId}
user={user}
/>
))}
<Button
text="Invite User"
onClick={() => {
handleSendInvite({userId});
}}
/>
</>);
}
MyForm.propTypes = {
getUsers: PropTypes.func.isRequired,
inviteNewUser: PropTypes.func.isRequired,
userId: PropTypes.number.isRequired,
currentUsers: PropTypes.arrayOf(UserInfo),
};
const mapStateToProps = (state) => {
const { id } = routerParamsSelector(state);
const currentUsers = selectCurrentUsers(state);
return {
userId: parseInt(id, 10),
currentUsers,
};
};
const mapDispatchToProps = {
getUsers,
inviteNewUser
};
export default connect(mapStateToProps, mapDispatchToProps)(MyForm);
Try async and await, it works.
const handleSendInvite = async (data) {
await inviteNewUser(data);
getUsers(data.userId);
}
It should be user instead of userId as you access the property of the object in the function.
<Button text="Invite User" onClick={() => { handleSendInvite(user); }} />
------------------------------------------------------------------------
const handleSendInvite = async (data) {
await inviteNewUser(data);
getUsers(data.userId);
}

how to pass user name dynamicaly?

hi , i have this kind of problem .. in my code i should pass the User name dynamicaly
here is my DashBoard wher i should pass the user name like "welcome ,UserName"
const Dashboard = ({logoutUser, user}) => {
const history = useHistory();
console.log("Dashboard user", user)
//here in console i can see the username that i pass
return (
<StyledFromArea bg={colors.dark2}>
<StyledTitle size={65}>Welcome : {user.name }
{ console.log("user.name", user.name)}
</StyledTitle>
{ // but here in console returning undefined , why? }
<Userinfo/>
<ButtonGroup>
<StyledButton to="#" onClick={() => logoutUser(history)}>Logout</StyledButton>
</ButtonGroup>
</StyledFromArea>
</div>
)
}
const mapStateToProps = ({session}) => ({
user: session.user,
});
export default connect(mapStateToProps, {logoutUser})(Dashboard)
//in logout acton i just deleting the sessionService.deleteSession()
//sessionService.deleteUser() and redirect to the home page

Issue in getting data from API in React

So i've basically got 2 components on my page.
First is the search component where the users need to type their username and second one where their stats get displayed
and here is my API request call in App.js
useEffect(()=>{
const fetchStats = async ()=> {
const result = await axios.get(`https://cors-anywhere.herokuapp.com/https://public-api.tracker.gg/v2/csgo/standard/profile/steam/${username}`,
{
headers: {
'TRN-Api-Key' : '***************************',
}
}
)
if(username !== null){
console.log(result.data)
setStats(result.data)
}
}
fetchStats()
},[username])
and this is the search component
const Search = ({setInputText, setUsername, inputText, username}) => {
const inputHandler = (e)=> {
setInputText(e.target.value)
}
const searchHandler = (e)=> {
e.preventDefault()
setUsername(inputText)
}
return (
<div>
<form>
<input value={inputText} onChange={inputHandler} type="text"/>
<button onClick={searchHandler}>Search</button>
</form>
</div>
)
}
What i'm having an issue with is when i click a button in the username component the value(username) from the form gets stored in the 'username' state in App.js. Now i'm using this code in the stats component.
const Stats = ({stats}) => {
return (
<div>
<h1>{stats.data.platformInfo.platformUserHandle}</h1>
</div>
)
}
export default Stats
Here stats.data.platformInfo.platformUserHandle doesn't exist when the app starts so it gives me a LOT of errors. How do i keep the app from crashing till the user has input something and data can be sent to the stats component?

React-admin's onSave method not passing form values

I am working on a React application and have been using the react-admin framework.
I need to pre-process the data coming from a form given that I need separate tables for a new employee and their address but don't want to split it into two screens.
I found the Using onSave To Alter the Form Submission Behavior section in the react-admin's Create/Edit View documentation and I applied it to my code (sample below) in hopes that it would allow me to process the data before getting into the dataProvider. Unfortunately, I can't seem to get the data out of the form and into the callback for the CreateEntity button module.
Create View
const CreateActions = props => (
<TopToolbar {...props}>
<CreateEntityButton props={props} variant="contained" label={"Create"}/>
</TopToolbar>
);
const EmployeeCreate = props => (
<Create {...props} >
<TabbedForm toolbar={<CreateActions record={props.record} redirect="show" />}>
<FormTab label="Identity">
<span >
<PersonInput />
</span>
</FormTab>
<FormTab label="Address">
<span >
<AddressInput />
</span>
</FormTab>
</TabbedForm>
</Create>
)
export default TequitiEmployeeCreate;
When I step through the logic in the browser, the callback function in the handleSave method (below) passes down undefined for both the values and the redirect parameters.
I expected the values object to contain all the input values from the TabbedForm so that it could be parsed and then passed over to my dataProvider module.
CreateEntityButton logic:
const CreateEntityButton = ({ ...props}) => {
const [create] = useCreate(props.props.resource);
const redirectTo = useRedirect();
const notify = useNotify();
const { basePath } = props;
const handleSave = useCallback(
(values, redirect) => { // <-------- undefined all the time
console.log(values);
console.log(redirect);
create(
{
payload: { data: { ...values } },
},
{
onSuccess: ({ data: newRecord }) => {
notify('ra.notification.created', 'info', {
smart_count: 1,
});
redirectTo(redirect, basePath, newRecord.id, newRecord);
},
}
);
},
[create, notify, redirectTo, basePath]
);
return <SaveButton
label={props.label}
variant={props.variant}
handleSubmitWithRedirect={handleSave}
/>;
};
I thought that perhaps having separate modules for PersonInput and AddressInput was to blame for this, but even consolidating all those components into a single one, didn't help.
Any help/thoughts would be helpful.
Turns out, I was mixing the example and was using handleSubmiutWithRedirect instead of the onSave action in the SaveButton.
const CreateEntityButton = ({ ...props}) => {
const resource = props.props.resource;
const redirectTo = useRedirect();
const notify = useNotify();
const { basePath } = props.props;
const dataProvider = useDataProvider();
const handleSave = useCallback(
(values) => {
const createPerson = new PersonAddressCreate(dataProvider);
createPerson.create(values, resource)
.then((data)=>{
notify('ra.notification.created', 'info', { smart_count: 1 });
redirectTo("show", basePath, data.id, data)
})
.catch((error)=>{
notify(error, 'error', { smart_count: 1 });
})
},
[notify, redirectTo, basePath]
);
return <SaveButton
{...props.props}
label={props.label}
variant={props.variant}
onSave={handleSave}
/>;
};

React native, cannot update during an existing state transition

I have a react native component. I got the error:
Cannot update during an existing state transition (such as within `render`). Render methods should be a pure function of props and state.
Code:
import....
class Register extends Component {
static navigationOptions = {
header: null,
};
async handleSubmit(values, customerCreate) {
const { email, password, firstName, lastName, phone } = values;
const input = { email, password, firstName, lastName, phone };
const customerCreateRes = await customerCreate({ variables: { input } });
const isCustomerCreated = !!customerCreateRes.data.customerCreate.customer.id;
if (isCustomerCreated) {
const isStoredCrediential = await storeCredential(email, password);
if (isStoredCrediential === true) {
// Store in redux
// Go to another screen
console.log('test');
}
}
}
render() {
return (
<Mutation mutation={CREATE_CUSTOMER_ACCOUNT}>
{
(customerCreate, { error, data }) => {
return (
<MainLayout
title="Create Account"
backButton
currentTab="profile"
navigation={this.props.navigation}
>
{ showError }
{ showSuccess }
<RegistrationForm
onSubmit={async (values) => this.handleSubmit(values, customerCreate)}
initialValues={this.props.initialValues}
/>
</MainLayout>
);
}
}
</Mutation>
);
}
}
const mapStateToProps = (state) => {
return {
....
};
};
export default connect(mapStateToProps)(Register);
CREATE_CUSTOMER_ACCOUNT is graphql:
import gql from 'graphql-tag';
export const CREATE_CUSTOMER_ACCOUNT = gql`
mutation customerCreate($input: CustomerCreateInput!) {
customerCreate(input: $input) {
userErrors {
field
message
}
customer {
id
}
}
}
`;
More detail here
Who is using the handleSubmit?
There is a button in the form call the handleSubmit, when press.
is this syntax correct onPress={handleSubmit} ?
const PrimaryButton = ({ label, handleSubmit, disabled }) => {
let buttonStyle = styles.button;
if (!disabled) {
buttonStyle = { ...buttonStyle, ...styles.primaryButton };
}
return (
<Button block primary={!disabled} disabled={disabled} onPress={handleSubmit} style={buttonStyle}>
<Text style={styles.buttonText}>{label}</Text>
</Button>
);
};
export default PrimaryButton;
Update 1:
If I remove customerCreate (coming from graphql), the error disappears. It means the async await is actually correct, but I need the customerCreate
Did you check with following code ?
onSubmit={(values) => this.handleSubmit(values, customerCreate)}
If you are trying to add arguments to a handler in recompose, make sure that you're defining your arguments correctly in the handler.
Also can be you're accidentally calling the onSubmit method in your render method, you probably want to double check how your onSubmit in RegistrationForm component.
Also you might want to try one more thing, moving async handleSubmit(values, customerCreate) { to handleSubmit = async(values, customerCreate) =>;
If this doesn't work, please add up your RegistrationForm component as well.
Bottom line, unless your aren't setting state in render, this will not happen.
It turns out the async await syntax is correct. The full original code (not posted here) contains Toast component react-base. The other developer is able to tell me to remove it and the error is gone. Sometimes it is hard to debug.

Resources