无法有条件地渲染组件

时间:2019-10-03 04:46:55

标签: reactjs

我正在尝试根据父级的状态有条件地渲染组件。但是我做不到。

在当前代码中,我可以在“ todos.length> 0”之后看到组件,但是当我开始在任何文本字段中键入内容时。

我的父组件:

function App() {
  const [title,setTitle] = React.useState("")
  const [desc, setDesc] = React.useState("")
  const [todos, setTodos] = React.useState([])

  const titleChange = (e) => {
           const value=e.target.value;
           setTitle(value)
  }

  const descChange = (e) => {
           const value=e.target.value;
           setDesc(value)
  }

  const handleCancel = () => {
    setTitle("");
    setDesc("")
  }

  const handleAdd = () => {
    const newTodos = todos;
    newTodos.push({
      title:title,
      description: desc
    });
    setTodos(newTodos)
  }

  return (
    <div >
      <label>Enter Title</label>
      <TextField onChange={(e) => titleChange(e)} value={title} />
      <label>Description</label>
      <TextArea onChange={(e) => descChange(e)} value = {desc}/>
      <Button onClick={handleCancel}>Cancel</Button>
      <Button onClick={handleAdd}>ADD</Button>
<div>
      {todos.length && <TodoList todos={todos} />}
      </div>
    </div>
  );
}

我的孩子部分:

export default function TodoList (props){

    React.useEffect(() => {
      console.log("mounted")
    })

    return (
        <div>
        {console.log(props)}
        </div>
    )
}

即使我尝试使用这种三元运算符,

todos.length ? <TodoList todos={todos} /> : null

6 个答案:

答案 0 :(得分:0)

我想您要显示待办事项列表

todos.length > 0 ? <TodoList todos={todos} /> : null

或者您可以通过这种方式

{ todos.lenght > 0 && <TodoList todos={todos} /> }

{ true && expression }返回expression { false && expression }返回false

答案 1 :(得分:0)

好吧,您丢失了一些东西,在handleAdd函数中,您只是推送到同一数组,因此React将具有与先前数组相同的引用,因此它将退出状态更新,您应该创建一个新数组从现有的 更改您的handleAdd为

const handleAdd = () => {
const newTodos = [ ...todos];
newTodos.push({
  title:title,
  description: desc
});
setTodos(newTodos)

}

这样,React将更新待办事项状态并更改

{todos.length && <TodoList todos={todos} />}

{todos.length > 0 && <TodoList todos={todos} />}

在您的子组件中再做一件事,而不是记录日志,获得div中数组的大小

<div>
    {props.todos.length}
</div>

希望有帮助

答案 2 :(得分:0)

不要改变状态。

只需更正您的CREATE TABLE twcs.twcs2 ( id int PRIMARY KEY, age int, name text ) WITH bloom_filter_fp_chance = 0.01 AND caching = {'keys': 'ALL', 'rows_per_partition': 'NONE'} AND comment = '' AND compaction = {'class': 'org.apache.cassandra.db.compaction.TimeWindowCompactionStrategy', 'compaction_window_size': '1', 'compaction_window_unit': 'MINUTES', 'max_threshold': '32', 'min_threshold': '4'} AND compression = {'chunk_length_in_kb': '64', 'class': 'org.apache.cassandra.io.compress.LZ4Compressor'} AND crc_check_chance = 1.0 AND dclocal_read_repair_chance = 0.1 AND default_time_to_live = 3600 AND gc_grace_seconds = 60 AND max_index_interval = 2048 AND memtable_flush_period_in_ms = 0 AND min_index_interval = 128 AND read_repair_chance = 0.0 AND speculative_retry = '99PERCENTILE'; 函数。

handleAdd

希望有帮助!

答案 3 :(得分:0)

component首次渲染时,todos length将始终0。因此{todos.length &&条件变为false

您应该使用类似的方法来避免此问题:

{todos.length >0  && <TodoList todos={todos} />}  

答案 4 :(得分:0)

我认为您的handleAdd函数应如下所示:

const handleAdd = () => {
   setTodos(todos => [...todos, { title: title, description: desc }]);
};

如果使用先前状态计算新状态,则可以将函数传递给setState: https://reactjs.org/docs/hooks-reference.html#functional-updates

答案 5 :(得分:-1)

这可能没有什么区别,但是您不需要在TextField组件中创建一个函数作为onChange的值。除非您的TextField组件无法正确处理,否则onChange会将事件传递给您的函数。换句话说,TextField组件的用法应如下所示……

<TextField onChange={titleChange} value={title} />

您的TextField组件本身应执行以下操作...

function TextField({onChange}) {
    function handleChange(event) {
        // Pass the event as an argument into the onChange prop
        onChange(event) 
    }

    return <input onChange={handleChange} />
}

如果您的TextField组件是第三方组件,则它们至少会传回一个值作为参数,因此请进行检查。

另一种可能性是您实际上是在handleAdd函数中更改待办事项。如果您想确保待办事项不发生变异,可以使用ES6将值添加到数组中的方法...

function handleAdd() {
  setTodos([
    ...todos, 
    {
      title: title,
      description: desc
    }
  ])
}

如果这些都不能帮助console.log在父组件中记录您的待办事项状态,看看它是否正在更改。