score:1

Accepted answer

edit: it turns out op is using material ui for this..meaning, the reason the input is showing a warning is due to material ui using proptypes. i suggested that op create a wrapper for the <input /> component and pass through all props. inside of the wrapper component you can just do: <inputwrapper value={props.value || ""} {...rest} /> and this covers things..

live demo

inputwrapper:

import react from 'react';
import { input } from '@material-ui/core';

export default function inputwrapper({ value, ...rest }) {
  return <input value={value || ""} {...rest} />
}

inputwrapper in use:

import react, { usestate, useeffect } from 'react';
import { render } from 'react-dom';
import inputwrapper from './inputwrapper.js';


function app(props) {
  const [state, setstate] = usestate({});

  useeffect(() => {
    setstate({
      name: props.name,
      age: props.age,
      haircolor: props.haircolor,
    })
  }, [props.name, props.age, props.haircolor]);

  const handlechange = (event, inputtype) => {
    setstate({...state, [inputtype]: event.target.value})
  }

  return(
    <div>
      {/* shows that you can pass through native <input /> props: */}
      {/* state.name is null here! warning is not thrown in the console! */}
      <inputwrapper value={state.name} fullwidth onchange={e => setstate({...state, name: e.target.value})} />
      <inputwrapper value={state.name} multiline onchange={e => setstate({...state, name: e.target.value})} />

      {object.keys(state).map((item, index) => {
        return (
          <div>
            <inputwrapper 
              key={`${item}_${index}`} 
              value={state[item]} 
              onchange={e => handlechange(e, item)} />
          </div>
        );
      })}
    </div>
  );
}

render(
  <app name={null} age={44} haircolor="blue" />, 
  document.getelementbyid('root')
);

original answer:

what is your use case? there is no reason to run checks and assign empty strings...

if you are trying to enforce that certain properties are used, please look into proptypes... if you are not wanting to enforce that certain props get used, i would recommend checking for a value during use of the variable. even if you set it to an empty string initially, you could still encounter errors down the line - i don't understand what you gain from an empty string.

i don't understand the use case - can you elaborate more on why you need to set it to an empty string?

if you really wanted to, you could verify like: usestate({two: props.two || ""}) ...but it is still unnecessary..

// notice how prop "two" is not being used..

function test(props) {
  const [state, setstate] = react.usestate({
    one: props.one,
    two: props.two
  })
  
  return(
    <div>
      <p>{state.one}</p>
      <p>even though <code>state.two</code> does not exist, there are no errors.. (at least for this demonstration)</p>
      <input type="text" value={state.two} />
      <input type="text" value={state.two} defaultvalue={"default"} />
      <p><i>if you really wanted to, you could verify like:</i><code>usestate(&#123;two: props.two || ""&#125;)</code><i>...but it is still unnecessary..</i></p>
    </div>
  );
}

reactdom.render(<test one="i am one" />, document.body)
code {
  margin: 0 10px;
  padding: 3px;
  color: red;
  background-color: lightgray;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.9.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.6/umd/react-dom.production.min.js"></script>

score:0

what about making method kickoutnullvalues() which will do what you want and then you can reuse it everywhere you need. that would be more elegant.

score:0

this is a tough question, i don't know the right answer. you already tried two ways, the different way that i normally do is,

if you just want to get the display right, i would just do

   <telephone data={props.telephone} />,
   const telephone = ({data}) => { if (!data) return null }

i found this is to allow the child component to ensure the validity of this issue rather than sorting out the data in the parent api level.

   telephone.defaultprops = {
     data: ''
   }

this further ensures that if the data is null, it'll be reset to '' by the defaultprops

the reason i prefer this way most of time is that i don't really want to mess with the origin truth of the api data.

of course your ways might be better if you do want to ensure the data is valid at all time :)

score:0

your code will start to have spaghetti-like qualities if you put the raw algorithm inside your callback. i recommend writing a function outside.

your usage of array#map is not correct, or rather you are using it in an unintended way. array#map is used to construct an entirely new array. you are simulating array#foreach. also, you're performing a falsey conditional check. null is one of many values that are considered false in javascript. namely, your pain points will probably be undefined, 0, and ''. if the only invalid return value is null, then check for null explicitly.

the enumerable that is for your intended use case is array#reduce:

function nullvaluereplacer(obj) {
  return object.entries(obj).reduce((newstatearr, [currentkey, currentvalue]) => {
    if (currentvalue === null) {
      newstatearr[currentkey] = ''
    } else {
      newstatearr[currentkey] = currentvalue
    }
    return newstatearr
  }, {});
}

as a side note, you might want to update your variable names. it's pretty deceptive that you have a variable called state_arr that is an object.

score:0

array of objects - little fix

you should not use key with map..

think about this: (similar to yours)

useeffect(() => {
  let state_arr = object.keys(props).map(prop =>  prop ? {prop} : { prop: '' });
  setstate(state_arr);
}, [])

by using this code you make an array with object and have easy access for every item

in case there is no nickname it will look like that:

[{ telephone: '245-4225-288' }, { nickname: '' }]

what do you think?


Related Query

More Query from same tag