0
votes

Expected

e.target.value returns me the value of the input in the form I submitted

Results

e contains a strange React changed object, SyntheticEvents?

return (
    <div>
        <form onSubmit={ onSubmitName }>
            <input id="name_field"
                   title="Name:"
                   placeholder={ user.name }/>
        </form>
    </div>
)

^ Above is my form, below is the onSubmit which is inside of a Redux mapDispatchToProps

const mapDispatchToProps = (dispatch) => {
    return {
        onSubmitName: (e) => {
            console.log('e', e);
            e.preventDefault();
            const name = document.getElementById('name_field').value;
            dispatch({ type: "CHANGE_NAME", payload: handleOnSubmit(name) })
        }
    }
}

e.preventDefault no longer exists on the new converted event.enter image description here

How is this now handled in React? The documentation provides no work arounds. To get e.preventDefault() to work again and e.target.value

Full code

import React from "react"
import { connect } from "react-redux"

const handleOnSubmit = (e) => {
    e.preventDefault();
    const name = document.getElementById('name_field').value;
    return name;
}

const mapDispatchToProps = (dispatch) => {
    return {
        onSubmitName: (e) => {
            console.log('e', e);
            e.preventDefault();
            const name = document.getElementById('name_field').value;
            dispatch({ type: "CHANGE_NAME", payload: handleOnSubmit(name) })
        }
    }
}

const NameField = ({ user, onSubmitName }) => {
    return (
        <div>
            <form onSubmit={ onSubmitName }>
                <input id="name_field"
                       title="Name:"
                       placeholder={ user.name }/>
            </form>
        </div>
    )
}

const NameContainer = connect(
    mapDispatchToProps
)(NameField);

export default NameContainer;
2
Why aren't you mapping` stateToProps`? - Umair Sarfraz
@Umair makes a good point. the first argument to connect is mapping state, if you don't need access to state there the first argument should be null - azium
var name seems to be a string when you pass it into handleOnSubmit() in dispatch({ type: "CHANGE_NAME", payload: handleOnSubmit(name) }), so the const handleOnSubmit function is accepting a string (not a SyntheticEvent), which does not have a preventDefault() method available - therobinkim
Yes. Also, you are missing value prop on input field. - Umair Sarfraz
@Umair when I add a value prop, it turns the form into a read-only field, however seems I can get around that with an onChange function, but I don't need that right now. - Leon Gaban

2 Answers

1
votes

The error I see in your code is that you're passing name to handleOnSubmit then trying to preventDefault on it which will fail because name is a string (the input value) not the event. You don't need to preventDefault twice.

const name = document.getElementById('name_field').value
dispatch({ 
  type: "CHANGE_NAME", 
  payload: handleOnSubmit(name) // name is a string
})

which calls:

const handleOnSubmit = (e) => { // e is name, not event.
  e.preventDefault(); // crashes 
  ..
  ..
}

I think you can just remove the outside function, handle preventing the default behaviour in your mapped dispatch call.

In the end your code should look like:

import React from "react"
import { connect } from "react-redux"

const mapDispatchToProps = (dispatch) => {
  return {
    onSubmitName: e => {
      e.preventDefault()
      const name = document.getElementById('name_field').value
      dispatch({ type: "CHANGE_NAME", payload: name })
    }
  }
}

const NameField = ({ user, onSubmitName }) => {
  return (
    <div>
      <form onSubmit={onSubmitName}>
        <input 
          id="name_field"
          title="Name:"
          placeholder={user.name}
        />
      </form>
    </div>
  )
}

const NameContainer = connect(
  null,
  mapDispatchToProps
)(NameField)

export default NameContainer

can check the webpackbin i made

0
votes

You are missing value prop on input element. Also, you need to passing in null as the first argument to connect

const NameField = ({ user, onSubmitName }) => {
    return (
        <div>
            <form onSubmit={ onSubmitName }>
                <input id="name_field"
                       title="Name:"
                       placeholder={ user.name }
                       value={ user.name }
                 />
            </form>
        </div>
    )
}

In your mapDispatchToProps:

const mapDispatchToProps = (dispatch) => {
    return {
        onSubmitName: (e) => {
            // use e.target.value
        }
    }
}