ReactJS Function Components object updates on second time - reactjs

I have a login page(Functional Component), When a user tries to login without entering the required fields, I have to show the error message(ex:"Email is required"). When an invalid field exists, I shouldn't make the API call.
But, without entering fields, when I click on login button, API call is done. Again clicking on login button stops the API call.
I have made this demo - https://stackblitz.com/edit/react-pd6vvk?file=login.js which explains the issue.
Steps to follow:
1.Click on login without filling any text values. You can see "API request made" statement when fields are invalid.
2.Again click on login button, "API Request stopped" statement is displayed now.
I am new to React and I don't know, the reason and the solution to fix this issue.
Can somebody please help me out?
Thank you,
Abhilash

Because, setValidFields has async behaviour :
validateLoginForm(); //<--- inside this setValidFieldsis async
console.log(validFields);
if (isFormValid()) { //<---- so,this will still have true value ( means not updated )
// inside validateLoginForm()
// this state change won,t be reflected immediately
setValidFields(validFields => ({
...validFields,
[key]: error.length == 0
}));
I have made few changes as per your code structure, as long as I know you will need useEffect also as shown in working demo.
WORKING DEMO

Related

Is it normal in React to use `useState` to manage whether a form has been submitted?

A basic online React tutorial is demonstrating how to create a React-based form with 3 fields (first name, last name, and email). Surprisingly to me, it has useState to manage whether or not a form has been submitted, which it uses to decide on whether to show a success message or not.
Please note that it does NOT make an actual form submission (i.e. no API calls) and so I am wondering whether it is using state only for simulation purposes here.
Here is a snippet:
const [submitted, setSubmitted] = useState(false);
...
{submitted && !values.lastName && <span id='last-name-error'>Please enter a last name</span>}
...
{showSuccess && <div class='success-message'>Success! Thank you for registering</div>}
...
Is it normal for real-world React applications to useState to manage whether or not a simple form such as 'contact us' or 'feedback', etc, has been submitted? My guess is that normally there would be no need to do so.
As the resulting API call, whether 'success' or 'fail' could simply be used to show the state of the error message. Thereafter, the form should ideally reset itself to allow for another submission. So, there would be no need to store the state of the submitted form. Am I correct in my understanding?
Your question is a little confusing. basically if you want to store a data in React and this data has direct effect on your application you mostly should save it in state. When you submit a form, the form onSubmit event handler will be called and you can do everything in that event handler. It's clear that in the tutorial submitted state is a flag to simulate the fetch process. Usually when you want to handle submitting a form and fetching API you should store 2 items in state:
Error and Loading
You should use loading flag to show a loading indicator during fetching API and use error to check if any error exist store and show it. If API fetches successfully you may redirect user to another page, show a notification or change some data in your state. It's up to you. But be sure the submitted state in your tutorial is just an example ans simulation. But it has real usages in real world! Hope it helps!
Here is an example: I want to add a user by fetching an api and i want if api fetches successfully add it to the list:
Sandbox

ReactJS console.log disappearing after some second

I am implementing SSO in my reactjs app on a button click and debugging one error by adding console.log to see the this.props.location variable. But as I click on the auth me button (that will trigger the sso auth) it shows the log for few second and then disappear. I have taken printscreen
I want to expand the object in console and view the attributes value , but unable to do it as it is disappearing. I have added wait timers also to hold the block but its getting hanged. Is there is a better way so that I can log the console.log's data to a file and view the errors peacefully without getting in a rush.
You have to use this code inside your submit button to prevent the default submit event.
onSubmitClicked = (e) => {
e.preventDefault()
//additional codes
}

Automatically try to sign in on initial page load using React, ideas on how to do that?

trying to use Microsoft's SSO with React, and I want to
on first load to activate the method to attempt to sign in. So that I don't need to ask the user to click a button, it should just be automatic.
I'm new to react and lifecycle methods, but it doesn't make sense to use componentWillLoad or componentDidLoad because it would just be checking everytime. Basically the whole site should be only viewable if logged in, so I believe setting up my protected paths after this should be doable
Any ideas on how to attempt this?
Edit:
useEffect = () => {
!this.props.account ? this.props.onSignIn() : <AuthWrapper/>
}, [];
You can use the useEffect hook in react and pass in an empty dependency so that the effect is only called once on initial page load. The same thing could be done with componentDidMount. You could put a function within the hook or lifecycle method to check if the user is logged in then show different pages based on if that value. Something like this:
useEffect(() => {
// check here if user is logged in
loggedIn ? showPageA : showPageB
}, []);

Clicking navigation button in Puppeteer returns null response? How to see which function is being clicked?

I'm trying to test clicking a button on a registration app to make sure that the page correctly navigates to the right page.
When I console.log out response in the code it returns an array that looks like this
[undefined, null]
However when I take a screenshot of the page or check the url, the click and navigation worked. It is on the correct page.
I don't understand why this is returning undefined/null. Also, I could not figure out how to test which function was being called when you click on the button.
I wanted to be able to see the actual function that is being called.
I'm using AngularJS 1.6, Mocha, Puppeteer 1.11, and Node 6.4.0
I'm also a junior dev so it could be something simple that I just didn't understand, please help!
it('should rederict to guest_sms_code state when clicking \'I have a guest code\'', async (function () {
var response = await (Promise.all([
page.waitForNavigation({waitUntil: 'domcontentloaded'}),
page.click('[ng-click="enterSmsCode()"]'),
]));
var url = await (page.url());
if (url.indexOf('guest_sms_code') === -1) {
assert.ok(false, 'The URL does not contain \'guest_sms_code\'')
}
}))
I'm not convinced that you can tell which method is called from a UI test. That's something that a JavaScript unit test can prove using, say, something like Mocha or Jest to test your codes behaviour. However an automated UI test, from my experience, won't tell you that. After all, you're trying to hide the inner workings of your app from an external user, right?
As for why the Promise.all([]) call is returning [undefined, null], well I can at least help you with that.
Firstly, you should have a look at the API documentation for both methods you've invoked in your test:
waitForNavigation docs: https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#pagewaitfornavigationoptions
click docs: https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#pageclickselector-options
In the case of waitForNavigation the response actually returns a Promise which may or may not have a Response value. Whether any data is returned with that Response is dependent on the navigation that occurs in the UI. In your case, you're seeing that undefined value in your array to indicate that there has not been any Response data returned from the navigation.
For the click method, this also just returns a resolved or rejected Promise with no data of any kind returned. So, naturally, you've no actual value returned here at all hence the null value being pushed to the array.

Can I automatically call handleSubmit in response to a state change using redux-form?

I would like to have a two part submit strategy for my redux-form. First, the user called submit on the form which calls a validation method. The response might have some warnings. I want the user to see the warnings, if any, and optionally continue with another submit that will be a real POST to the server rest api.
If there are no warnings, I would like the component to submit automatically. I am trying to kick this off from the componentWillReceiveProps method.
The problem is that nextProps.handleSubmit(this.doSubmit2of2); does not call this.doSubmit2of2. Execution just steps over that call.
componentWillReceiveProps(nextProps) {
//boolean that indicates validation just occured against the server
if (nextProps.storeWithValidation) {
//the user hit submit, first it was validated, if no issues, go ahead and try to create
if (nextProps.storeValidationOk) {
//fire off create store
nextProps.handleSubmit(this.doSubmit2of2);
}
else {
//there are validation issues of some kind, let the user see them
//do nothing here and let the render method do its thing with the props
}
}
}
I have found the discussion here: https://github.com/erikras/redux-form/issues/67, but in my case the submit is happening as result of a particular server response. Also, I realize that there are validation features of redux-form. Am I designing too far outside of the intended framework convention?
Also, I have thought of redesigning my server api, but I would like to know how far I can go with this current approach of automatically resubmitting after a response from the server.
From what I understand you want to submit the form remotely after a response from the server. You can create a remote submit following this example from the docs. Then you can dispatch(submit('yourFormName')) whenever you want to as many times as you want to.

Resources