The docs say that I should be able to set the page via DataTablesApiInstance.page(pageNumber), but I can't get it to work.
All the other API methods like search and order seem to work fine. 
Here's my code:
$(document)
    .on('preInit.dt', (ev, settings) => {
        let tableId = ev.target.id;
        let tableState = _.get(['datatables', tableId], history.state) || {};
        let api = new $.fn.dataTable.Api(settings);
        if(tableState.hasOwnProperty('page')) {
            api.page(tableState.page); // <-- problem is here; page doesn't get set
        }
        if(tableState.hasOwnProperty('search')) {
            api.search(tableState.search);
        }
        if(tableState.hasOwnProperty('order')) {
            api.order(tableState.order);
        }
        const setState = (key, value) => {
            history.replaceState(_.set(['datatables', tableId, key], value, history.state), '');
        };
        api.on('page', ev => {
            let info = api.page.info();
            // console.log('page', tableId, info.page);
            setState('page', info.page);
        });
        api.on('order', ev => {
            let order = api.order();
            // console.log('order', tableId, order);
            setState('order', order);
        });
        api.on('search', ev => {
            setState('search', api.search());
        });
    });
The method is hit, but the page isn't set. Am I using the wrong API method? Is there another way to set the page before the data loads?
I'm using datatables.net@1.10.12.
If I defer the call to init instead of preInit then the correct page number is highlighted, but the data is still from the first page. If I add a 0ms delay on top of that (as below), it does work, but causes a 2nd data fetch + draw.
if(tableState.page) {
    api.on('init', ev => {
        setTimeout(() => {
            api.page(tableState.page).draw('page');
        }, 0);
    });
}
How can I set the page without incurring a 2nd ajax request?