Joj*_*oji 6 javascript ecmascript-6 reactjs es6-generator
我有一个字符串数组要显示const array = ["one", "two", "three"]; 。
UI 最初显示数组中的第一项,即"one"。从那里我有一个按钮right,单击它会显示下一个项目或字符串,即two,然后three,之后three应该返回one并再次从那里开始。我还有一个left按钮,单击时它显示前一个项目或字符串,如果当前字符串是two,则前一个字符串是one,然后从one开始three并向后走。
我正在使用生成器来做到这一点。这是我的尝试
function* stepGen(steps) {
let index = 0;
while (true) {
const direction = yield steps[index];
index = (index + (direction === "forward" ? 1 : -1)) % steps.length;
}
}
const array = ["one", "two", "three"];
let gen = stepGen(array);
const getNext = () => gen.next("forward").value;
const getPrev = () => gen.next("backward").value;
export default function App() {
const [current, setCurrent] = useState(() => getNext());
const onRight = () => {
const next = getNext();
setCurrent(next);
};
const onLeft = () => {
const prev = getPrev();
setCurrent(prev);
};
return (
<div className="App">
<h1>{current}</h1>
<button onClick={onLeft}>left</button>
<button onClick={onRight}>right</button>
</div>
);
}
Run Code Online (Sandbox Code Playgroud)
这是一个现场演示,您可以使用 https://codesandbox.io/s/cyclethrough1-deh8p?file=/src/App.js
显然当前的行为是有问题的。有很多问题不知道原因和解决方案:
twonotone开头。我想这与我如何启动状态有关currentconst [current, setCurrent] = useState(() => getNext());
Run Code Online (Sandbox Code Playgroud)
我认为() => getNext()只有在组件首次安装时才会被调用一次,所以current应该one从一开始就调用。
我尝试启动状态
const [current, setCurrent] = useState(array[0]);
Run Code Online (Sandbox Code Playgroud)
它确实从数组中的第一项开始,one但您必须单击right按钮两次才能使其转到two。这是此变体的现场演示https://codesandbox.io/s/cyclethrough2-5gews?file=/src/App.js
left不起作用。它完全坏了。right不过按钮可以用。不知道为什么。问题在于getPrev余数 ( %) 运算符,与模运算不同,当余数为负数时,它会返回负结果。要解决这个问题,请改用模函数:
// modulo function
const mod = (n, r) => ((n % r) + r) % r;
Run Code Online (Sandbox Code Playgroud)
为了解决第一次渲染时的问题,请在组件外部创建初始值。这是一个解决方法,因为我找不到该错误的原因。
const init = getNext(); // get the initial value
export default function App() {
const [current, setCurrent] = useState(init); // use init value
Run Code Online (Sandbox Code Playgroud)
我还可以省去三元组的需要,通过分别传入和来1确定增量。-1getNextgetPrev
完整代码示例(沙箱):
// modulo function
const mod = (n, r) => ((n % r) + r) % r;
function* stepGen(steps) {
let index = 0;
while (true) {
const dir = yield steps[index];
index = mod(index + dir, steps.length); // use mod function instead of remainder operator
}
}
const array = ['one', 'two', 'three'];
const gen = stepGen(array);
const getPrev = () => gen.next(-1).value; // dec directly
const getNext = () => gen.next(1).value; // inc directly
const init = getNext(); // get the initial value
export default function App() {
const [current, setCurrent] = useState(init); // use init value
const onLeft = () => {
const next = getPrev();
setCurrent(next);
};
const onRight = () => {
const prev = getNext();
setCurrent(prev);
};
return (
<div className="App">
<h1>{current}</h1>
<button onClick={onLeft}>left</button>
<button onClick={onRight}>right</button>
</div>
);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
253 次 |
| 最近记录: |