这是我制作的代码笔,它显示了我正在尝试做的事情。
https://codepen.io/doliphin/pen/JjRbqJO
从 each 的本地范围<Block />,他们能够访问所有其他块的值。
但是,以下代码使用相同的思想,不允许从其本地范围<InputBlock />访问状态。valueLookup
具体来说,我正在查看InputBlock. 我添加了评论以显示我得到的输出。
import * as React from 'react';
import ContentEditable from "react-contenteditable";
import './UserInput.css';
function debug(header, value, footer) {
// just a way of printing pretty debug stuff
}
const insertAndReturn = (someArray, item, index) => (
// inserts item at index of someArray and returns it
);
const InputBlock = ({startText, blockId, valueLookup, setValueLookup}) => {
const text = React.useRef(startText ? startText.toString() : '');
const editableRef = React.useRef(null);
const updateParent = (event) => {
console.log(`updating parent of ${blockId}...`)
setValueLookup( oldObject => {
let returnObject = {};
returnObject[blockId] = event.target.value;
debug('updated object (within updateParent) = ', {...oldObject, ...returnObject});
// -> updated object (within updateParent) = {<blockId>: <someString>}
return {...oldObject, ...returnObject}
})
debug('valueLookup = ', valueLookup);
// -> valueLookup = {}
}
const handleChange = (event) => {
text.current = event.target.value;
updateParent(event);
}
const handleBlur = (event) => {
updateParent(event);
}
return (
<ContentEditable
className={"user-input"}
html={text.current}
innerRef={editableRef}
onChange={handleChange}
onBlur={handleBlur}
/>
)
}
const UserInput = () => {
// an array of all components to be rendered
const [ blockArray, setBlockArray ] = React.useState([]);
// an object containing the text value of all blocks
const [ blockValues, setBlockValues ] = React.useState({});
// an ordered list of blockIds
const [ idArray, setIdArray ] = React.useState([]);
// just an ID counter quite obvious idk
const [ lastId, setLastId ] = React.useState(0);
const newId = (count=1) => {
// generates a certain number of Ids
};
// create a default input block
const newInputBlock = (id, startText="") => (
<InputBlock
startText={startText}
blockId={id}
valueLookup={blockValues}
setValueLookup={setBlockValues}
/>
)
// insert a block
const insertBlock = (position, block) => {
let blockId = newId();
// fixes the position so that it always works
if ( position > blockArray.length || position === "end" ) {
position = blockArray.length;
};
if ( position < 0 ) { position = 0 };
// default block
if ( !block ) {
block = <div style={{display: "inline-block"}}>
{newInputBlock(blockId, "")}
</div>
}
// updates the ordered states
setBlockArray( oldArray => insertAndReturn(oldArray, block, position) );
setIdArray( oldArray => insertAndReturn(oldArray, blockId, position) );
}
return <div>
{blockArray}
</div>
}
export default UserInput
为什么此代码的工作方式与我的 codepen 不同?(道具始终是最新的并且可以在本地访问)