Nan*_*ane 5 javascript ajax reactjs draftjs axios
我正在尝试使用草稿js构建contentEditor.这个功能正是从Facebook这样的网址中提取数据.但我坚持这部分.回调无效.
首先,我包裹着我的状态,compositeDecorator像这样
constructor(props) {
super(props);
const compositeDecorator = new CompositeDecorator([
.... {
strategy: linkStrategy,
component: decorateComponentWithProps(linkComp, {
passit
})
}
....
]);
}
// This is my strategy
function linkStrategy(contentBlock, callback, contentState) {
findLinkInText(LINK_REGEX, contentBlock, callback)
}
function findLinkInText(regex, contentBlock, callback) {
const text = contentBlock.getText();
let matchArr, start;
if ((matchArr = regex.exec(text)) !== null) {
start = matchArr.index;
let URL = matchArr[0];
console.log(URL);
axios.post('/url', {
url: URL
}).then(response => {
passit = response.data
//not working
callback(start, start + URL.length)
})
//working
callback(start, start + URL.length)
}
}
Run Code Online (Sandbox Code Playgroud)
如果回调不起作用,组件将不会呈现..我不知道这是一个基本的JavaScript问题.但问题是我想从我的服务器获取url数据,我必须通过props将数据传递给我的组件并进行渲染.
答案的最新消息
function findLinkInText(regex, contentBlock, callback) {
const text = contentBlock.getText();
let matchArr, start;
if ((matchArr = regex.exec(text)) !== null) {
start = matchArr.index;
let url = matchArr[0];
axios.post('/url', {
url: URL
}).then(response => {
passit = response.data
handleWithAxiosCallBack(start, start + matchArr[0].length, callback)
}).catch(err => console.log(err))
}
}
function handleWithAxiosCallBack(start, startLength, callback) {
console.log(callback); //Spits out the function But Not working
callback(start, startLength)
}
Run Code Online (Sandbox Code Playgroud)
下面描述的技术将帮助您实现您期望的行为。
为什么您的解决方案不起作用:需要执行的所需操作callback未执行的原因是,draft期望callback被称为同步。由于您正在使用一个async函数(axios api 调用)并且异步调用callback没有效果。
解决方案:这可能不是一个有效的解决方案,但可以完成工作。简而言之,您所要做的就是将调用结果存储axios在变量中(临时),然后触发re-render您的editor,提前检索结果存储并使用它来调用回调。
我根据这里的示例进行跟踪。假设您将编辑器状态存储在组件的状态中。下面是一个伪代码,您可能需要根据您的需要来实现。
让我们假设您的组件状态如下所示,它保存Editor的状态。
constructor(props){
super(props);
// .. your composite decorators
// this is your component state holding editors state
this.state = {
editorState: EditorState.createWithContent(..)
}
// use this to temporarily store the results from axios.
this.tempResults = {};
}
Run Code Online (Sandbox Code Playgroud)
假设您将其渲染Editor为如下所示。注意ref. 这里,编辑器引用存储在组件的editor变量中,您稍后可以访问该变量。使用字符串作为引用可以,但这是存储引用的推荐方法。
<Editor
ref={ (editor) => this.editor }
editorState={this.state.editorState}
onChange={this.onChange}
// ...your props
/>
Run Code Online (Sandbox Code Playgroud)
在您的组件中,编写一个函数来使用 currentState 更新编辑器,这将强制re-render. 确保此函数绑定到您的组件,以便我们获得正确的this(上下文)。
forceRenderEditor = () => {
this.editor.update(this.state.editorState);
}
Run Code Online (Sandbox Code Playgroud)
在您的findLinkInText函数中执行以下操作。
首先确保它(findLinkInText)绑定到您的组件,以便我们获得正确的this. 您可以使用箭头函数来执行此操作或将其绑定在组件构造函数中。
其次,检查我们是否有在组件构造函数中声明的url已结果。tempResults如果我们有一个,则立即使用适当的参数调用回调。
如果我们还没有结果,则进行调用并将结果存储在tempResults. 存储后,调用已经定义的this.forceRenderEditor方法,该方法将调用草稿来重新检查,这一次,由于我们已将结果存储在 中tempResults,因此将调用回调并反映适当的更改。
function findLinkInText(regex, contentBlock, callback) {
const text = contentBlock.getText();
let matchArr, start;
if ((matchArr = regex.exec(text)) !== null) {
start = matchArr.index;
let URL = matchArr[0];
console.log(URL);
// do we have the result already,??
// call the callback based on the result.
if(this.tempResults[url]) {
// make the computations and call the callback() with necessary args
} else {
// if we don't have a result, call the api
axios.post('/url', {
url: URL
}).then(response => {
this.tempResults[url] = response.data;
this.forceRenderEditor();
// store the result in this.tempResults and
// then call the this.forceRenderEditor
// You might need to debounce the forceRenderEditor function
})
}
}
}
Run Code Online (Sandbox Code Playgroud)
笔记:
memoization。上面描述的是一种简单的。axios api由于您的结果是记忆的,如果调用结果不会因相同的输入而改变,这可能对您来说是一个优势。对于同一查询,您可能不必再次访问 api。callback。debounce该方法来避免重复更新。forceRenderEditordraft使用或建议async回调的地方。您可能需要咨询图书馆团队是否支持/需要此类功能。(如果需要,请进行更改,如果他们的团队同意的话,请提出 PR。)更新
要绑定,您可以移动组件内的函数并按以下方式编写。
linkStrategy = (contentBlock, callback, contentState) => {
this.findLinkInText(LINK_REGEX, contentBlock, callback)
}
findLinkInText = (...args) => {
}
Run Code Online (Sandbox Code Playgroud)
在你的构造函数中你可以这样调用它
const compositeDecorator = new CompositeDecorator([
.... {
strategy: this.linkStrategy,
component: decorateComponentWithProps(linkComp, {
passit
})
}
....
]);
}
Run Code Online (Sandbox Code Playgroud)
或者,如果您想跨多个组件重用该函数,则可以通过以下方式绑定它。state但请确保在所有共享组件中使用相同的组件(或使用回调来定义自定义状态)
你的构造函数会像
const compositeDecorator = new CompositeDecorator([
.... {
strategy: linkStrategy.bind(this),
component: decorateComponentWithProps(linkComp, {
passit
})
}
....
]);
}
Run Code Online (Sandbox Code Playgroud)
你的链接策略将是这样的
function linkStrategy(contentBlock, callback, contentState) {
findLinkInText.call(this,LINK_REGEX, contentBlock, callback);
}
Run Code Online (Sandbox Code Playgroud)
您可以使用上述任一方法来绑定您的函数。
| 归档时间: |
|
| 查看次数: |
1052 次 |
| 最近记录: |