我有一个名为TodoList
const TodoItem = ({ checked, children }) =>
(<TouchableOpacity
style={{ backgroundColor: checked && 'red'}}>
{children}
</TouchableOpacity>
);
const TodoList = props => {
const {
options = [],
onSelect,
...rest
} = props;
const [selectedOptionIndex, setSelectedOptionIndex] = useState(null);
useEffect(() => {
onSelect(options[selectedOptionIndex]);
}, [onSelect, options, selectedOptionIndex]);
const renderItem = (o, index) => {
return (
<TodoItem
key={o + index}
onPress={() => setSelectedOptionIndex(index)}
checked={index === selectedOptionIndex}>
{index === selectedOptionIndex && <Tick />}
<Text>{o}</Text>
</TodoItem>
);
};
return (
<View {...rest}>{options.map(renderItem)}</View>
);
};
export default TodoList;
我有一个名为Container
export default function() {
const [item, setItem] = setState(null);
return (
<Screen>
<TodoList options={[1,2,3]} onSelect={(i) => setItem(i)} />
</Screen>
)
}
无论何时选择onSelect
,我都希望使用TodoItem
从子组件到父组件进行回调。但是,无论何时调用onSelect
,我的TodoList
都会重新呈现,而我的selectedOptionIndex
被重置。因此,我的checked
标志只会在重置为true
之前短暂地变为false
。
如果我删除了onSelect
回调,它将正常工作。但是我需要setState
来照顾孩子和父母。我该怎么办?
答案 0 :(得分:0)
很难说出为什么会发生这种情况,最有可能是因为容器的状态在变化,导致所有内容重新呈现。
但是这种事情应该可以帮到你。
const { render } = ReactDOM;
const { useEffect, useState } = React;
const ToDoItem = ({checked, label, onChange, style}) => {
const handleChange = event => onChange(event);
return (
<div style={style}>
<input type="checkbox" checked={checked} onChange={handleChange}/>
{label}
</div>
);
}
const ToDoList = ({items, onChosen}) => {
const [selected, setSelected] = useState([]);
const handleChange = item => event => {
let s = [...selected];
s.includes(item) ? s.splice(s.indexOf(item), 1) : s.push(item);
setSelected(s);
onChosen(s);
}
return (
<div>
{items && items.map(i => {
let s = selected.includes(i);
return (
<ToDoItem
key={i}
label={i}
onChange={handleChange(i)}
checked={s}
style={{textDecoration: s ? 'line-through' : ''}}/>
)
})}
</div>
);
}
const App = () => {
const [chosen, setChosen] = useState();
const handleChosen = choices => {
setChosen(choices);
}
return (
<div>
<ToDoList items={["Rock", "Paper", "Scissors"]} onChosen={handleChosen} />
{chosen && chosen.length > 0 && <pre>Chosen: {JSON.stringify(chosen,null,2)}</pre>}
</div>
);
}
render(<App />, document.body)
<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.9.0/umd/react-dom.production.min.js"></script>
答案 1 :(得分:0)
原来,我的顶级组件Screen
导致了此重新渲染。在我的Screen
功能组件中,我在return
const Content = scroll
? contentProps => {
const { style: contentContainerStyle } = contentProps;
return (
<ScrollView {...contentContainerStyle}>
{contentProps.children}
</ScrollView>
);
}
: View;
return (
<Content>{children}</Content>
)
每当我的状态改变时,它都会以某种方式(不确定为什么)使孩子们重新渲染。
我通过删除函数对其进行了修复,并使其仅返回一个View
const Content = scroll ? ScrollView : View;